summaryrefslogtreecommitdiffstats
path: root/WebCore/plugins
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:15 -0800
commit1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353 (patch)
tree4457a7306ea5acb43fe05bfe0973b1f7faf97ba2 /WebCore/plugins
parent9364f22aed35e1a1e9d07c121510f80be3ab0502 (diff)
downloadexternal_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.zip
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.gz
external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'WebCore/plugins')
-rw-r--r--WebCore/plugins/MimeType.cpp70
-rw-r--r--WebCore/plugins/MimeType.h52
-rw-r--r--WebCore/plugins/MimeType.idl29
-rw-r--r--WebCore/plugins/MimeTypeArray.cpp94
-rw-r--r--WebCore/plugins/MimeTypeArray.h60
-rw-r--r--WebCore/plugins/MimeTypeArray.idl26
-rw-r--r--WebCore/plugins/Plugin.cpp91
-rw-r--r--WebCore/plugins/Plugin.h65
-rw-r--r--WebCore/plugins/Plugin.idl29
-rw-r--r--WebCore/plugins/PluginArray.cpp99
-rw-r--r--WebCore/plugins/PluginArray.h62
-rw-r--r--WebCore/plugins/PluginArray.idl27
-rw-r--r--WebCore/plugins/PluginData.cpp63
-rw-r--r--WebCore/plugins/PluginData.h74
-rw-r--r--WebCore/plugins/PluginDatabase.cpp375
-rw-r--r--WebCore/plugins/PluginDatabase.h56
-rw-r--r--WebCore/plugins/PluginDebug.h10
-rw-r--r--WebCore/plugins/PluginInfoStore.cpp12
-rw-r--r--WebCore/plugins/PluginInfoStore.h14
-rw-r--r--WebCore/plugins/PluginMainThreadScheduler.cpp115
-rw-r--r--WebCore/plugins/PluginMainThreadScheduler.h86
-rw-r--r--WebCore/plugins/PluginPackage.cpp166
-rw-r--r--WebCore/plugins/PluginPackage.h83
-rw-r--r--WebCore/plugins/PluginQuirkSet.h1
-rw-r--r--WebCore/plugins/PluginStream.cpp57
-rw-r--r--WebCore/plugins/PluginStream.h35
-rw-r--r--WebCore/plugins/PluginView.cpp922
-rw-r--r--WebCore/plugins/PluginView.h174
-rw-r--r--WebCore/plugins/android/PlugInInfoStoreAndroid.cpp85
-rw-r--r--WebCore/plugins/android/PluginDatabaseAndroid.cpp347
-rw-r--r--WebCore/plugins/android/PluginDatabaseAndroid.h91
-rw-r--r--WebCore/plugins/android/PluginDebug.h44
-rw-r--r--WebCore/plugins/android/PluginPackageAndroid.cpp504
-rw-r--r--WebCore/plugins/android/PluginPackageAndroid.h152
-rw-r--r--WebCore/plugins/android/PluginViewAndroid.cpp567
-rw-r--r--WebCore/plugins/android/PluginViewAndroid.h176
-rw-r--r--WebCore/plugins/android/npapi.cpp200
-rw-r--r--WebCore/plugins/android/npfunctions.h201
-rw-r--r--WebCore/plugins/gtk/PluginDataGtk.cpp73
-rw-r--r--WebCore/plugins/gtk/PluginPackageGtk.cpp284
-rw-r--r--WebCore/plugins/gtk/PluginViewGtk.cpp586
-rw-r--r--WebCore/plugins/gtk/gtk2xtbin.c946
-rw-r--r--WebCore/plugins/gtk/gtk2xtbin.h158
-rw-r--r--WebCore/plugins/gtk/xembed.h64
-rw-r--r--WebCore/plugins/mac/PluginDataMac.mm76
-rw-r--r--WebCore/plugins/npapi.cpp39
-rw-r--r--WebCore/plugins/npfunctions.h38
-rw-r--r--WebCore/plugins/qt/PluginDataQt.cpp108
-rw-r--r--WebCore/plugins/qt/PluginPackageQt.cpp220
-rw-r--r--WebCore/plugins/qt/PluginViewQt.cpp483
-rw-r--r--WebCore/plugins/win/PluginDataWin.cpp72
-rw-r--r--WebCore/plugins/win/PluginDatabaseWin.cpp316
-rw-r--r--WebCore/plugins/win/PluginMessageThrottlerWin.cpp123
-rw-r--r--WebCore/plugins/win/PluginMessageThrottlerWin.h72
-rw-r--r--WebCore/plugins/win/PluginPackageWin.cpp322
-rw-r--r--WebCore/plugins/win/PluginViewWin.cpp1224
-rw-r--r--WebCore/plugins/wx/PluginDataWx.cpp44
-rw-r--r--WebCore/plugins/wx/PluginPackageWx.cpp74
-rw-r--r--WebCore/plugins/wx/PluginViewWx.cpp140
59 files changed, 6771 insertions, 4005 deletions
diff --git a/WebCore/plugins/MimeType.cpp b/WebCore/plugins/MimeType.cpp
new file mode 100644
index 0000000..c4b051c
--- /dev/null
+++ b/WebCore/plugins/MimeType.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "MimeType.h"
+
+#include "Frame.h"
+#include "Page.h"
+#include "Plugin.h"
+#include "PluginData.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+MimeType::MimeType(PassRefPtr<PluginData> pluginData, unsigned index)
+ : m_pluginData(pluginData)
+ , m_index(index)
+{
+}
+
+MimeType::~MimeType()
+{
+}
+
+const String &MimeType::type() const
+{
+ return m_pluginData->mimes()[m_index]->type;
+}
+
+const String &MimeType::suffixes() const
+{
+ return m_pluginData->mimes()[m_index]->suffixes;
+}
+
+const String &MimeType::description() const
+{
+ return m_pluginData->mimes()[m_index]->desc;
+}
+
+PassRefPtr<Plugin> MimeType::enabledPlugin() const
+{
+ const Page* p = m_pluginData->page();
+ if (!p || !p->settings()->arePluginsEnabled())
+ return 0;
+
+ const PluginInfo *info = m_pluginData->mimes()[m_index]->plugin;
+ const Vector<PluginInfo*>& plugins = m_pluginData->plugins();
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ if (plugins[i] == info)
+ return Plugin::create(m_pluginData.get(), i);
+ }
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/MimeType.h b/WebCore/plugins/MimeType.h
new file mode 100644
index 0000000..5207918
--- /dev/null
+++ b/WebCore/plugins/MimeType.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef MimeType_h
+#define MimeType_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RefCounted.h>
+
+#include "PluginData.h"
+
+namespace WebCore {
+
+ class Plugin;
+ class String;
+
+ class MimeType : public RefCounted<MimeType> {
+ public:
+ static PassRefPtr<MimeType> create(PassRefPtr<PluginData> pluginData, unsigned index) { return adoptRef(new MimeType(pluginData, index)); }
+ ~MimeType();
+
+ const String &type() const;
+ const String &suffixes() const;
+ const String &description() const;
+ PassRefPtr<Plugin> enabledPlugin() const;
+
+ private:
+ MimeType(PassRefPtr<PluginData>, unsigned index);
+ RefPtr<PluginData> m_pluginData;
+ unsigned m_index;
+ };
+
+}
+
+#endif
diff --git a/WebCore/plugins/MimeType.idl b/WebCore/plugins/MimeType.idl
new file mode 100644
index 0000000..ac75cc2
--- /dev/null
+++ b/WebCore/plugins/MimeType.idl
@@ -0,0 +1,29 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+module window {
+
+ interface MimeType {
+ readonly attribute DOMString type;
+ readonly attribute DOMString suffixes;
+ readonly attribute DOMString description;
+ readonly attribute Plugin enabledPlugin;
+ };
+
+}
diff --git a/WebCore/plugins/MimeTypeArray.cpp b/WebCore/plugins/MimeTypeArray.cpp
new file mode 100644
index 0000000..9bc4fcf
--- /dev/null
+++ b/WebCore/plugins/MimeTypeArray.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "MimeTypeArray.h"
+
+#include "AtomicString.h"
+#include "Frame.h"
+#include "Page.h"
+#include "Plugin.h"
+#include "PluginData.h"
+
+namespace WebCore {
+
+MimeTypeArray::MimeTypeArray(Frame* frame)
+ : m_frame(frame)
+{
+}
+
+MimeTypeArray::~MimeTypeArray()
+{
+}
+
+unsigned MimeTypeArray::length() const
+{
+ PluginData* data = getPluginData();
+ if (!data)
+ return 0;
+ return data->mimes().size();
+}
+
+PassRefPtr<MimeType> MimeTypeArray::item(unsigned index)
+{
+ PluginData* data = getPluginData();
+ if (!data)
+ return 0;
+ const Vector<MimeClassInfo*>& mimes = data->mimes();
+ if (index >= mimes.size())
+ return 0;
+ return MimeType::create(data, index).get();
+}
+
+bool MimeTypeArray::canGetItemsForName(const AtomicString& propertyName)
+{
+ PluginData *data = getPluginData();
+ if (!data)
+ return 0;
+ const Vector<MimeClassInfo*>& mimes = data->mimes();
+ for (unsigned i = 0; i < mimes.size(); ++i) {
+ if (mimes[i]->type == propertyName)
+ return true;
+ }
+ return false;
+}
+
+PassRefPtr<MimeType> MimeTypeArray::nameGetter(const AtomicString& propertyName)
+{
+ PluginData *data = getPluginData();
+ if (!data)
+ return 0;
+ const Vector<MimeClassInfo*>& mimes = data->mimes();
+ for (unsigned i = 0; i < mimes.size(); ++i) {
+ if (mimes[i]->type == propertyName)
+ return MimeType::create(data, i).get();
+ }
+ return 0;
+}
+
+PluginData* MimeTypeArray::getPluginData() const
+{
+ if (!m_frame)
+ return 0;
+ Page* p = m_frame->page();
+ if (!p)
+ return 0;
+ return p->pluginData();
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/MimeTypeArray.h b/WebCore/plugins/MimeTypeArray.h
new file mode 100644
index 0000000..392a812
--- /dev/null
+++ b/WebCore/plugins/MimeTypeArray.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef MimeTypeArray_h
+#define MimeTypeArray_h
+
+#include "MimeType.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+ class ExecState;
+};
+
+namespace WebCore {
+
+ class AtomicString;
+ class Frame;
+ class PluginData;
+
+ // FIXME: Generated JSMimeTypeArray.cpp doesn't include JSMimeType.h for toJS
+ JSC::JSValue* toJS(JSC::ExecState*, MimeType*);
+
+ class MimeTypeArray : public RefCounted<MimeTypeArray> {
+ public:
+ static PassRefPtr<MimeTypeArray> create(Frame* frame) { return adoptRef(new MimeTypeArray(frame)); }
+ ~MimeTypeArray();
+
+ void disconnectFrame() { m_frame = 0; }
+
+ unsigned length() const;
+ PassRefPtr<MimeType> item(unsigned index);
+ bool canGetItemsForName(const AtomicString& propertyName);
+ PassRefPtr<MimeType> nameGetter(const AtomicString& propertyName);
+ private:
+ MimeTypeArray(Frame*);
+ PluginData* getPluginData() const;
+
+ Frame* m_frame;
+ };
+}
+
+#endif
diff --git a/WebCore/plugins/MimeTypeArray.idl b/WebCore/plugins/MimeTypeArray.idl
new file mode 100644
index 0000000..067f2a8
--- /dev/null
+++ b/WebCore/plugins/MimeTypeArray.idl
@@ -0,0 +1,26 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+module window {
+
+ interface [HasNameGetter, HasIndexGetter] MimeTypeArray {
+ readonly attribute unsigned long length;
+ };
+
+}
diff --git a/WebCore/plugins/Plugin.cpp b/WebCore/plugins/Plugin.cpp
new file mode 100644
index 0000000..d095c55
--- /dev/null
+++ b/WebCore/plugins/Plugin.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "Plugin.h"
+
+#include "AtomicString.h"
+#include "PluginData.h"
+#include "Frame.h"
+
+namespace WebCore {
+
+Plugin::Plugin(PluginData* pluginData, unsigned index)
+ : m_pluginData(pluginData)
+ , m_index(index)
+{
+}
+
+Plugin::~Plugin()
+{
+}
+
+String Plugin::name() const
+{
+ return m_pluginData->plugins()[m_index]->name;
+}
+
+String Plugin::filename() const
+{
+ return m_pluginData->plugins()[m_index]->file;
+}
+
+String Plugin::description() const
+{
+ return m_pluginData->plugins()[m_index]->desc;
+}
+
+unsigned Plugin::length() const
+{
+ return m_pluginData->plugins()[m_index]->mimes.size();
+}
+
+PassRefPtr<MimeType> Plugin::item(unsigned index)
+{
+ const Vector<PluginInfo*>& plugins = m_pluginData->plugins();
+ if (index >= plugins[m_index]->mimes.size())
+ return 0;
+
+ MimeClassInfo* mime = plugins[m_index]->mimes[index];
+
+ const Vector<MimeClassInfo*>& mimes = m_pluginData->mimes();
+ for (unsigned i = 0; i < mimes.size(); ++i)
+ if (mimes[i] == mime)
+ return MimeType::create(m_pluginData.get(), i).get();
+ return 0;
+}
+
+bool Plugin::canGetItemsForName(const AtomicString& propertyName)
+{
+ const Vector<MimeClassInfo*>& mimes = m_pluginData->mimes();
+ for (unsigned i = 0; i < mimes.size(); ++i)
+ if (mimes[i]->type == propertyName)
+ return true;
+ return false;
+}
+
+PassRefPtr<MimeType> Plugin::nameGetter(const AtomicString& propertyName)
+{
+ const Vector<MimeClassInfo*>& mimes = m_pluginData->mimes();
+ for (unsigned i = 0; i < mimes.size(); ++i)
+ if (mimes[i]->type == propertyName)
+ return MimeType::create(m_pluginData.get(), i).get();
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/Plugin.h b/WebCore/plugins/Plugin.h
new file mode 100644
index 0000000..1d1384a
--- /dev/null
+++ b/WebCore/plugins/Plugin.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef Plugin_h
+#define Plugin_h
+
+#include "MimeType.h"
+#include <wtf/RefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace JSC {
+ class ExecState;
+}
+
+namespace WebCore {
+
+ class AtomicString;
+ class Plugin;
+ class String;
+
+ // FIXME: Generated JSPlugin.cpp doesn't include JSMimeType.h for toJS
+ JSC::JSValue* toJS(JSC::ExecState*, MimeType*);
+
+ class PluginData;
+
+ class Plugin : public RefCounted<Plugin> {
+ public:
+ static PassRefPtr<Plugin> create(PluginData* pluginData, unsigned index) { return adoptRef(new Plugin(pluginData, index)); }
+ ~Plugin();
+
+ String name() const;
+ String filename() const;
+ String description() const;
+
+ unsigned length() const;
+
+ PassRefPtr<MimeType> item(unsigned index);
+ bool canGetItemsForName(const AtomicString& propertyName);
+ PassRefPtr<MimeType> nameGetter(const AtomicString& propertyName);
+
+ private:
+ Plugin(PluginData*, unsigned index);
+ RefPtr<PluginData> m_pluginData;
+ unsigned m_index;
+ };
+
+}
+
+#endif
diff --git a/WebCore/plugins/Plugin.idl b/WebCore/plugins/Plugin.idl
new file mode 100644
index 0000000..988f371
--- /dev/null
+++ b/WebCore/plugins/Plugin.idl
@@ -0,0 +1,29 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+module window {
+
+ interface [HasNameGetter, HasIndexGetter] Plugin {
+ readonly attribute DOMString name;
+ readonly attribute DOMString filename;
+ readonly attribute DOMString description;
+ readonly attribute unsigned long length;
+ };
+
+}
diff --git a/WebCore/plugins/PluginArray.cpp b/WebCore/plugins/PluginArray.cpp
new file mode 100644
index 0000000..d304829
--- /dev/null
+++ b/WebCore/plugins/PluginArray.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "PluginArray.h"
+
+#include "AtomicString.h"
+#include "Frame.h"
+#include "Page.h"
+#include "Plugin.h"
+#include "PluginData.h"
+
+namespace WebCore {
+
+PluginArray::PluginArray(Frame* frame)
+ : m_frame(frame)
+{
+}
+
+PluginArray::~PluginArray()
+{
+}
+
+unsigned PluginArray::length() const
+{
+ PluginData* data = getPluginData();
+ if (!data)
+ return 0;
+ return data->plugins().size();
+}
+
+PassRefPtr<Plugin> PluginArray::item(unsigned index)
+{
+ PluginData* data = getPluginData();
+ if (!data)
+ return 0;
+ const Vector<PluginInfo*>& plugins = data->plugins();
+ if (index >= plugins.size())
+ return 0;
+ return Plugin::create(data, index).get();
+}
+
+bool PluginArray::canGetItemsForName(const AtomicString& propertyName)
+{
+ PluginData* data = getPluginData();
+ if (!data)
+ return 0;
+ const Vector<PluginInfo*>& plugins = data->plugins();
+ for (unsigned i = 0; i < plugins.size(); ++i) {
+ if (plugins[i]->name == propertyName)
+ return true;
+ }
+ return false;
+}
+
+PassRefPtr<Plugin> PluginArray::nameGetter(const AtomicString& propertyName)
+{
+ PluginData* data = getPluginData();
+ if (!data)
+ return 0;
+ const Vector<PluginInfo*>& plugins = data->plugins();
+ for (unsigned i = 0; i < plugins.size(); ++i) {
+ if (plugins[i]->name == propertyName)
+ return Plugin::create(data, i).get();
+ }
+ return 0;
+}
+
+void PluginArray::refresh(bool reload)
+{
+ Page::refreshPlugins(reload);
+}
+
+PluginData* PluginArray::getPluginData() const
+{
+ if (!m_frame)
+ return 0;
+ Page* p = m_frame->page();
+ if (!p)
+ return 0;
+ return p->pluginData();
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/PluginArray.h b/WebCore/plugins/PluginArray.h
new file mode 100644
index 0000000..e51775d
--- /dev/null
+++ b/WebCore/plugins/PluginArray.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PluginArray_h
+#define PluginArray_h
+
+#include "Plugin.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+ class ExecState;
+}
+
+namespace WebCore {
+
+ class AtomicString;
+ class Frame;
+ class PluginData;
+
+ // FIXME: Generated JSPluginArray.cpp doesn't include JSPlugin.h for toJS
+ JSC::JSValue* toJS(JSC::ExecState*, Plugin*);
+
+ class PluginArray : public RefCounted<PluginArray> {
+ public:
+ static PassRefPtr<PluginArray> create(Frame* frame) { return adoptRef(new PluginArray(frame)); }
+ ~PluginArray();
+
+ void disconnectFrame() { m_frame = 0; }
+
+ unsigned length() const;
+ PassRefPtr<Plugin> item(unsigned index);
+ bool canGetItemsForName(const AtomicString& propertyName);
+ PassRefPtr<Plugin> nameGetter(const AtomicString& propertyName);
+
+ void refresh(bool reload);
+ private:
+ PluginArray(Frame*);
+ PluginData* getPluginData() const;
+
+ Frame* m_frame;
+ };
+}
+
+#endif
diff --git a/WebCore/plugins/PluginArray.idl b/WebCore/plugins/PluginArray.idl
new file mode 100644
index 0000000..58f68b5
--- /dev/null
+++ b/WebCore/plugins/PluginArray.idl
@@ -0,0 +1,27 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+module window {
+
+ interface [HasNameGetter, HasIndexGetter] PluginArray {
+ readonly attribute unsigned long length;
+ void refresh(in boolean reload);
+ };
+
+}
diff --git a/WebCore/plugins/PluginData.cpp b/WebCore/plugins/PluginData.cpp
new file mode 100644
index 0000000..ca4bda5
--- /dev/null
+++ b/WebCore/plugins/PluginData.cpp
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2000 Harri Porten (porten@kde.org)
+ Copyright (C) 2000 Daniel Molkentin (molkentin@kde.org)
+ Copyright (C) 2000 Stefan Schimanski (schimmi@kde.org)
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All Rights Reserved.
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "PluginData.h"
+
+namespace WebCore {
+
+PluginData::PluginData(const Page* page)
+ : m_page(page)
+{
+ initPlugins();
+
+ for (unsigned i = 0; i < m_plugins.size(); ++i) {
+ const PluginInfo* plugin = m_plugins[i];
+ for (unsigned j = 0; j < plugin->mimes.size(); ++j)
+ m_mimes.append(plugin->mimes[j]);
+ }
+}
+
+PluginData::~PluginData()
+{
+ deleteAllValues(m_plugins);
+ deleteAllValues(m_mimes);
+}
+
+bool PluginData::supportsMimeType(const String& mimeType) const
+{
+ for (unsigned i = 0; i < m_mimes.size(); ++i)
+ if (m_mimes[i]->type == mimeType)
+ return true;
+ return false;
+}
+
+String PluginData::pluginNameForMimeType(const String& mimeType) const
+{
+ for (unsigned i = 0; i < m_mimes.size(); ++i)
+ if (m_mimes[i]->type == mimeType)
+ return m_mimes[i]->plugin->name;
+ return String();
+}
+
+}
diff --git a/WebCore/plugins/PluginData.h b/WebCore/plugins/PluginData.h
new file mode 100644
index 0000000..b2866bf
--- /dev/null
+++ b/WebCore/plugins/PluginData.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PluginData_h
+#define PluginData_h
+
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include "PlatformString.h"
+
+namespace WebCore {
+
+ class Page;
+ struct PluginInfo;
+
+ struct MimeClassInfo {
+ String type;
+ String desc;
+ String suffixes;
+ PluginInfo* plugin;
+ };
+
+ struct PluginInfo {
+ String name;
+ String file;
+ String desc;
+ Vector<MimeClassInfo*> mimes;
+ };
+
+ // FIXME: merge with PluginDatabase in the future
+ class PluginData : public RefCounted<PluginData> {
+ public:
+ static PassRefPtr<PluginData> create(const Page* page) { return adoptRef(new PluginData(page)); }
+ ~PluginData();
+
+ void disconnectPage() { m_page = 0; }
+ const Page* page() const { return m_page; }
+
+ const Vector<PluginInfo*>& plugins() const { return m_plugins; }
+ const Vector<MimeClassInfo*>& mimes() const { return m_mimes; }
+
+ bool supportsMimeType(const String& mimeType) const;
+ String pluginNameForMimeType(const String& mimeType) const;
+
+ static void refresh();
+
+ private:
+ PluginData(const Page*);
+ void initPlugins();
+
+ Vector<PluginInfo*> m_plugins;
+ Vector<MimeClassInfo*> m_mimes;
+ const Page* m_page;
+ };
+
+}
+
+#endif
diff --git a/WebCore/plugins/PluginDatabase.cpp b/WebCore/plugins/PluginDatabase.cpp
new file mode 100644
index 0000000..e3b86ae
--- /dev/null
+++ b/WebCore/plugins/PluginDatabase.cpp
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginDatabase.h"
+
+#include "Frame.h"
+#include "KURL.h"
+#include "PluginPackage.h"
+#include <stdlib.h>
+
+namespace WebCore {
+
+PluginDatabase* PluginDatabase::installedPlugins()
+{
+ static PluginDatabase* plugins = 0;
+
+ if (!plugins) {
+ plugins = new PluginDatabase;
+ plugins->setPluginDirectories(PluginDatabase::defaultPluginDirectories());
+ plugins->refresh();
+ }
+
+ return plugins;
+}
+
+bool PluginDatabase::isMIMETypeRegistered(const String& mimeType)
+{
+ if (mimeType.isNull())
+ return false;
+ if (m_registeredMIMETypes.contains(mimeType))
+ return true;
+ // No plugin was found, try refreshing the database and searching again
+ return (refresh() && m_registeredMIMETypes.contains(mimeType));
+}
+
+void PluginDatabase::addExtraPluginDirectory(const String& directory)
+{
+ m_pluginDirectories.append(directory);
+ refresh();
+}
+
+bool PluginDatabase::refresh()
+{
+ bool pluginSetChanged = false;
+
+ if (!m_plugins.isEmpty()) {
+ PluginSet pluginsToUnload;
+ getDeletedPlugins(pluginsToUnload);
+
+ // Unload plugins
+ PluginSet::const_iterator end = pluginsToUnload.end();
+ for (PluginSet::const_iterator it = pluginsToUnload.begin(); it != end; ++it)
+ remove(it->get());
+
+ pluginSetChanged = !pluginsToUnload.isEmpty();
+ }
+
+ HashSet<String> paths;
+ getPluginPathsInDirectories(paths);
+
+ HashMap<String, time_t> pathsWithTimes;
+
+ // We should only skip unchanged files if we didn't remove any plugins above. If we did remove
+ // any plugins, we need to look at every plugin file so that, e.g., if the user has two versions
+ // of RealPlayer installed and just removed the newer one, we'll pick up the older one.
+ bool shouldSkipUnchangedFiles = !pluginSetChanged;
+
+ HashSet<String>::const_iterator pathsEnd = paths.end();
+ for (HashSet<String>::const_iterator it = paths.begin(); it != pathsEnd; ++it) {
+ time_t lastModified;
+ if (!getFileModificationTime(*it, lastModified))
+ continue;
+
+ pathsWithTimes.add(*it, lastModified);
+
+ // If the path's timestamp hasn't changed since the last time we ran refresh(), we don't have to do anything.
+ if (shouldSkipUnchangedFiles && m_pluginPathsWithTimes.get(*it) == lastModified)
+ continue;
+
+ if (RefPtr<PluginPackage> oldPackage = m_pluginsByPath.get(*it)) {
+ ASSERT(!shouldSkipUnchangedFiles || oldPackage->lastModified() != lastModified);
+ remove(oldPackage.get());
+ }
+
+ RefPtr<PluginPackage> package = PluginPackage::createPackage(*it, lastModified);
+ if (package && add(package.release()))
+ pluginSetChanged = true;
+ }
+
+ // Cache all the paths we found with their timestamps for next time.
+ pathsWithTimes.swap(m_pluginPathsWithTimes);
+
+ if (!pluginSetChanged)
+ return false;
+
+ m_registeredMIMETypes.clear();
+
+ // Register plug-in MIME types
+ PluginSet::const_iterator end = m_plugins.end();
+ for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+ // Get MIME types
+ MIMEToDescriptionsMap::const_iterator map_end = (*it)->mimeToDescriptions().end();
+ for (MIMEToDescriptionsMap::const_iterator map_it = (*it)->mimeToDescriptions().begin(); map_it != map_end; ++map_it) {
+ m_registeredMIMETypes.add(map_it->first);
+ }
+ }
+
+ return true;
+}
+
+Vector<PluginPackage*> PluginDatabase::plugins() const
+{
+ Vector<PluginPackage*> result;
+
+ PluginSet::const_iterator end = m_plugins.end();
+ for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it)
+ result.append((*it).get());
+
+ return result;
+}
+
+int PluginDatabase::preferredPluginCompare(const void* a, const void* b)
+{
+ PluginPackage* pluginA = *static_cast<PluginPackage* const*>(a);
+ PluginPackage* pluginB = *static_cast<PluginPackage* const*>(b);
+
+ return pluginA->compare(*pluginB);
+}
+
+PluginPackage* PluginDatabase::pluginForMIMEType(const String& mimeType)
+{
+ if (mimeType.isEmpty())
+ return 0;
+
+ String key = mimeType.lower();
+ PluginSet::const_iterator end = m_plugins.end();
+
+ Vector<PluginPackage*, 2> pluginChoices;
+
+ for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+ if ((*it)->mimeToDescriptions().contains(key))
+ pluginChoices.append((*it).get());
+ }
+
+ if (pluginChoices.isEmpty())
+ return 0;
+
+ qsort(pluginChoices.data(), pluginChoices.size(), sizeof(PluginPackage*), PluginDatabase::preferredPluginCompare);
+
+ return pluginChoices[0];
+}
+
+String PluginDatabase::MIMETypeForExtension(const String& extension) const
+{
+ if (extension.isEmpty())
+ return String();
+
+ PluginSet::const_iterator end = m_plugins.end();
+ String mimeType;
+ Vector<PluginPackage*, 2> pluginChoices;
+ HashMap<PluginPackage*, String> mimeTypeForPlugin;
+
+ for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+ MIMEToExtensionsMap::const_iterator mime_end = (*it)->mimeToExtensions().end();
+
+ for (MIMEToExtensionsMap::const_iterator mime_it = (*it)->mimeToExtensions().begin(); mime_it != mime_end; ++mime_it) {
+ const Vector<String>& extensions = mime_it->second;
+ bool foundMapping = false;
+ for (unsigned i = 0; i < extensions.size(); i++) {
+ if (equalIgnoringCase(extensions[i], extension)) {
+ PluginPackage* plugin = (*it).get();
+ pluginChoices.append(plugin);
+ mimeTypeForPlugin.add(plugin, mime_it->first);
+ foundMapping = true;
+ break;
+ }
+ }
+ if (foundMapping)
+ break;
+ }
+ }
+
+ if (pluginChoices.isEmpty())
+ return String();
+
+ qsort(pluginChoices.data(), pluginChoices.size(), sizeof(PluginPackage*), PluginDatabase::preferredPluginCompare);
+
+ return mimeTypeForPlugin.get(pluginChoices[0]);
+}
+
+PluginPackage* PluginDatabase::findPlugin(const KURL& url, String& mimeType)
+{
+ PluginPackage* plugin = pluginForMIMEType(mimeType);
+ String filename = url.string();
+
+ if (!plugin) {
+ String filename = url.lastPathComponent();
+ if (!filename.endsWith("/")) {
+ int extensionPos = filename.reverseFind('.');
+ if (extensionPos != -1) {
+ String extension = filename.substring(extensionPos + 1);
+
+ mimeType = MIMETypeForExtension(extension);
+ plugin = pluginForMIMEType(mimeType);
+ }
+ }
+ }
+
+ // FIXME: if no plugin could be found, query Windows for the mime type
+ // corresponding to the extension.
+
+ return plugin;
+}
+
+void PluginDatabase::getDeletedPlugins(PluginSet& plugins) const
+{
+ PluginSet::const_iterator end = m_plugins.end();
+ for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+ if (!fileExists((*it)->path()))
+ plugins.add(*it);
+ }
+}
+
+bool PluginDatabase::add(PassRefPtr<PluginPackage> prpPackage)
+{
+ ASSERT_ARG(prpPackage, prpPackage);
+
+ RefPtr<PluginPackage> package = prpPackage;
+
+ if (!m_plugins.add(package).second)
+ return false;
+
+ m_pluginsByPath.add(package->path(), package);
+ return true;
+}
+
+void PluginDatabase::remove(PluginPackage* package)
+{
+ m_plugins.remove(package);
+ m_pluginsByPath.remove(package->path());
+}
+
+#if !PLATFORM(WIN_OS) || PLATFORM(WX)
+// For Safari/Win the following three methods are implemented
+// in PluginDatabaseWin.cpp, but if we can use WebCore constructs
+// for the logic we should perhaps move it here under XP_WIN?
+
+Vector<String> PluginDatabase::defaultPluginDirectories()
+{
+ Vector<String> paths;
+
+ // Add paths specific to each platform
+#if defined(XP_UNIX)
+ String userPluginPath = homeDirectoryPath();
+ userPluginPath.append(String("/.mozilla/plugins"));
+ paths.append(userPluginPath);
+
+ userPluginPath = homeDirectoryPath();
+ userPluginPath.append(String("/.netscape/plugins"));
+ paths.append(userPluginPath);
+
+ paths.append("/usr/lib/browser/plugins");
+ paths.append("/usr/local/lib/mozilla/plugins");
+ paths.append("/usr/lib/firefox/plugins");
+ paths.append("/usr/lib64/browser-plugins");
+ paths.append("/usr/lib/browser-plugins");
+ paths.append("/usr/lib/mozilla/plugins");
+ paths.append("/usr/local/netscape/plugins");
+ paths.append("/opt/mozilla/plugins");
+ paths.append("/opt/mozilla/lib/plugins");
+ paths.append("/opt/netscape/plugins");
+ paths.append("/opt/netscape/communicator/plugins");
+ paths.append("/usr/lib/netscape/plugins");
+ paths.append("/usr/lib/netscape/plugins-libc5");
+ paths.append("/usr/lib/netscape/plugins-libc6");
+ paths.append("/usr/lib64/netscape/plugins");
+ paths.append("/usr/lib64/mozilla/plugins");
+
+ String mozHome(getenv("MOZILLA_HOME"));
+ mozHome.append("/plugins");
+ paths.append(mozHome);
+
+ Vector<String> mozPaths;
+ String mozPath(getenv("MOZ_PLUGIN_PATH"));
+ mozPath.split(UChar(':'), /* allowEmptyEntries */ false, mozPaths);
+ paths.append(mozPaths);
+#elif defined(XP_MACOSX)
+ String userPluginPath = homeDirectoryPath();
+ userPluginPath.append(String("/Library/Internet Plug-Ins"));
+ paths.append(userPluginPath);
+ paths.append("/Library/Internet Plug-Ins");
+#elif defined(XP_WIN)
+ String userPluginPath = homeDirectoryPath();
+ userPluginPath.append(String("\\Application Data\\Mozilla\\plugins"));
+ paths.append(userPluginPath);
+#endif
+
+ // Add paths specific to each port
+#if PLATFORM(QT)
+ Vector<String> qtPaths;
+ String qtPath(getenv("QTWEBKIT_PLUGIN_PATH"));
+ qtPath.split(UChar(':'), /* allowEmptyEntries */ false, qtPaths);
+ paths.append(qtPaths);
+#endif
+
+ return paths;
+}
+
+bool PluginDatabase::isPreferredPluginDirectory(const String& path)
+{
+ String preferredPath = homeDirectoryPath();
+
+#if defined(XP_UNIX)
+ preferredPath.append(String("/.mozilla/plugins"));
+#elif defined(XP_MACOSX)
+ preferredPath.append(String("/Library/Internet Plug-Ins"));
+#elif defined(XP_WIN)
+ preferredPath.append(String("\\Application Data\\Mozilla\\plugins"));
+#endif
+
+ // TODO: We should normalize the path before doing a comparison.
+ return path == preferredPath;
+}
+
+void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const
+{
+ // FIXME: This should be a case insensitive set.
+ HashSet<String> uniqueFilenames;
+
+#if defined(XP_UNIX) || defined(ANDROID)
+ String fileNameFilter("*.so");
+#else
+ String fileNameFilter("");
+#endif
+
+ Vector<String>::const_iterator dirsEnd = m_pluginDirectories.end();
+ for (Vector<String>::const_iterator dIt = m_pluginDirectories.begin(); dIt != dirsEnd; ++dIt) {
+ Vector<String> pluginPaths = listDirectory(*dIt, fileNameFilter);
+ Vector<String>::const_iterator pluginsEnd = pluginPaths.end();
+ for (Vector<String>::const_iterator pIt = pluginPaths.begin(); pIt != pluginsEnd; ++pIt) {
+ if (!fileExists(*pIt))
+ continue;
+
+ paths.add(*pIt);
+ }
+ }
+}
+
+#endif // !PLATFORM(WIN_OS)
+
+}
diff --git a/WebCore/plugins/PluginDatabase.h b/WebCore/plugins/PluginDatabase.h
index 71181b0..ccb3821 100644
--- a/WebCore/plugins/PluginDatabase.h
+++ b/WebCore/plugins/PluginDatabase.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,22 +27,18 @@
#ifndef PluginDatabase_H
#define PluginDatabase_H
-#ifdef ANDROID_PLUGINS
-
-#include "PluginDatabaseAndroid.h"
-
-namespace WebCore {
- typedef PluginDatabaseAndroid PluginDatabase;
-}
-
-#else // !defined(ANDROID_PLUGINS)
+#include "PlatformString.h"
+#include "PluginPackage.h"
+#include "StringHash.h"
#include <wtf/Vector.h>
#include <wtf/HashSet.h>
-#include "PlatformString.h"
-#include "PluginPackage.h"
-#include "StringHash.h"
+#if defined(ANDROID_PLUGINS)
+namespace android {
+ class WebSettings;
+}
+#endif
namespace WebCore {
class Element;
@@ -49,36 +46,51 @@ namespace WebCore {
class IntSize;
class KURL;
class PluginPackage;
- class PluginView;
typedef HashSet<RefPtr<PluginPackage>, PluginPackageHash> PluginSet;
class PluginDatabase {
public:
static PluginDatabase* installedPlugins();
- PluginView* createPluginView(Frame* parentFrame, const IntSize&, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
bool refresh();
Vector<PluginPackage*> plugins() const;
bool isMIMETypeRegistered(const String& mimeType);
- void addExtraPluginPath(const String&);
+ void addExtraPluginDirectory(const String&);
+
+ static bool isPreferredPluginDirectory(const String& directory);
+ static int preferredPluginCompare(const void*, const void*);
+
+ PluginPackage* findPlugin(const KURL&, String& mimeType);
+
private:
- void setPluginPaths(const Vector<String>& paths) { m_pluginPaths = paths; }
- PluginSet getPluginsInPaths() const;
+ void setPluginDirectories(const Vector<String>& directories) { m_pluginDirectories = directories; }
+
+ void getPluginPathsInDirectories(HashSet<String>&) const;
+ void getDeletedPlugins(PluginSet&) const;
+
+ // Returns whether the plugin was actually added or not (it won't be added if it's a duplicate of an existing plugin).
+ bool add(PassRefPtr<PluginPackage>);
+ void remove(PluginPackage*);
- PluginPackage* findPlugin(const KURL& url, String& mimeType);
PluginPackage* pluginForMIMEType(const String& mimeType);
String MIMETypeForExtension(const String& extension) const;
- static Vector<String> defaultPluginPaths();
+ static Vector<String> defaultPluginDirectories();
- Vector<String> m_pluginPaths;
+ Vector<String> m_pluginDirectories;
HashSet<String> m_registeredMIMETypes;
PluginSet m_plugins;
+ HashMap<String, RefPtr<PluginPackage> > m_pluginsByPath;
+ HashMap<String, time_t> m_pluginPathsWithTimes;
+
+#if defined(ANDROID_PLUGINS)
+ // Need access to setPluginDirectories() to change the default
+ // path after startup.
+ friend class ::android::WebSettings;
+#endif
};
} // namespace WebCore
-#endif // !defined(ANDROID_PLUGINS)
-
#endif
diff --git a/WebCore/plugins/PluginDebug.h b/WebCore/plugins/PluginDebug.h
index 31d9891..a57c209 100644
--- a/WebCore/plugins/PluginDebug.h
+++ b/WebCore/plugins/PluginDebug.h
@@ -23,13 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PLUGIN_DEBUG_H__
-#define PLUGIN_DEBUG_H__
+#ifndef PluginDebug_h
+#define PluginDebug_h
#include "Logging.h"
#include "npruntime_internal.h"
-static const char* errorStrings[] = {
+#if !LOG_DISABLED
+
+static const char* const errorStrings[] = {
"No errors occurred.", /* NPERR_NO_ERROR */
"Error with no specific error code occurred.", /* NPERR_GENERIC_ERROR */
"Invalid instance passed to the plug-in.", /* NPERR_INVALID_INSTANCE_ERROR */
@@ -47,6 +49,8 @@ static const char* errorStrings[] = {
"Unknown error code"
};
+#endif
+
#define LOG_NPERROR(err) if (err != NPERR_NO_ERROR) LOG_VERBOSE(Plugin, "%s\n", errorStrings[err])
#define LOG_PLUGIN_NET_ERROR() LOG_VERBOSE(Plugin, "Stream failed due to problems with network, disk I/O, lack of memory, or other problems.\n")
diff --git a/WebCore/plugins/PluginInfoStore.cpp b/WebCore/plugins/PluginInfoStore.cpp
index d95ba9e..732a1e1 100644
--- a/WebCore/plugins/PluginInfoStore.cpp
+++ b/WebCore/plugins/PluginInfoStore.cpp
@@ -25,6 +25,9 @@
#include "config.h"
#include "PluginInfoStore.h"
+
+#include "KURL.h"
+#include "PluginData.h"
#include "PluginDatabase.h"
#include "PluginPackage.h"
@@ -71,7 +74,14 @@ unsigned PluginInfoStore::pluginCount() const
String PluginInfoStore::pluginNameForMIMEType(const String& mimeType)
{
- // FIXME 5629139: Implement this method on Windows.
+ String mimeTypeCopy(mimeType);
+
+ if (PluginPackage* package = PluginDatabase::installedPlugins()->findPlugin(KURL(), mimeTypeCopy)) {
+ ASSERT(mimeType == mimeTypeCopy);
+
+ return package->name();
+ }
+
return String();
}
diff --git a/WebCore/plugins/PluginInfoStore.h b/WebCore/plugins/PluginInfoStore.h
index 7471015..302cf8c 100644
--- a/WebCore/plugins/PluginInfoStore.h
+++ b/WebCore/plugins/PluginInfoStore.h
@@ -33,20 +33,6 @@ namespace WebCore {
struct PluginInfo;
-struct MimeClassInfo {
- String type;
- String desc;
- String suffixes;
- PluginInfo* plugin;
-};
-
-struct PluginInfo {
- String name;
- String file;
- String desc;
- Vector<MimeClassInfo*> mimes;
-};
-
class PluginInfoStore {
public:
PluginInfo *createPluginInfoForPluginAtIndex(unsigned);
diff --git a/WebCore/plugins/PluginMainThreadScheduler.cpp b/WebCore/plugins/PluginMainThreadScheduler.cpp
new file mode 100644
index 0000000..a7067f1
--- /dev/null
+++ b/WebCore/plugins/PluginMainThreadScheduler.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginMainThreadScheduler.h"
+
+namespace WebCore {
+
+PluginMainThreadScheduler& PluginMainThreadScheduler::scheduler()
+{
+ static PluginMainThreadScheduler& scheduler = *new PluginMainThreadScheduler;
+
+ return scheduler;
+}
+
+PluginMainThreadScheduler::PluginMainThreadScheduler()
+ : m_callPending(false)
+{
+}
+
+void PluginMainThreadScheduler::scheduleCall(NPP npp, MainThreadFunction function, void* userData)
+{
+ MutexLocker lock(m_queueMutex);
+
+ CallQueueMap::iterator it = m_callQueueMap.find(npp);
+ if (it == m_callQueueMap.end())
+ return;
+
+ it->second.append(Call(function, userData));
+
+ if (!m_callPending) {
+ callOnMainThread(mainThreadCallback, this);
+ m_callPending = true;
+ }
+}
+
+void PluginMainThreadScheduler::registerPlugin(NPP npp)
+{
+ MutexLocker lock(m_queueMutex);
+
+ ASSERT(!m_callQueueMap.contains(npp));
+ m_callQueueMap.set(npp, Deque<Call>());
+}
+
+void PluginMainThreadScheduler::unregisterPlugin(NPP npp)
+{
+ MutexLocker lock(m_queueMutex);
+
+ ASSERT(m_callQueueMap.contains(npp));
+ m_callQueueMap.remove(npp);
+}
+
+void PluginMainThreadScheduler::dispatchCallsForPlugin(NPP npp, const Deque<Call>& calls)
+{
+ Deque<Call>::const_iterator end = calls.end();
+ for (Deque<Call>::const_iterator it = calls.begin(); it != end; ++it) {
+ // Check if the plug-in has been destroyed.
+ {
+ MutexLocker lock(m_queueMutex);
+ if (!m_callQueueMap.contains(npp))
+ return;
+ }
+
+ (*it).performCall();
+ }
+}
+
+void PluginMainThreadScheduler::dispatchCalls()
+{
+ m_queueMutex.lock();
+ CallQueueMap copy(m_callQueueMap);
+
+ {
+ // Empty all the queues in the original map
+ CallQueueMap::iterator end = m_callQueueMap.end();
+ for (CallQueueMap::iterator it = m_callQueueMap.begin(); it != end; ++it)
+ it->second.clear();
+ }
+
+ m_callPending = false;
+ m_queueMutex.unlock();
+
+ CallQueueMap::iterator end = copy.end();
+ for (CallQueueMap::iterator it = copy.begin(); it != end; ++it)
+ dispatchCallsForPlugin(it->first, it->second);
+}
+
+void PluginMainThreadScheduler::mainThreadCallback(void* context)
+{
+ static_cast<PluginMainThreadScheduler*>(context)->dispatchCalls();
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/PluginMainThreadScheduler.h b/WebCore/plugins/PluginMainThreadScheduler.h
new file mode 100644
index 0000000..8872d56
--- /dev/null
+++ b/WebCore/plugins/PluginMainThreadScheduler.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginMainThreadScheduler_h
+#define PluginMainThreadScheduler_h
+
+#include <wtf/Deque.h>
+#include <wtf/HashMap.h>
+#include <wtf/MainThread.h>
+#include <wtf/Threading.h>
+
+typedef struct _NPP NPP_t;
+typedef NPP_t* NPP;
+
+namespace WebCore {
+
+class PluginMainThreadScheduler {
+public:
+ typedef void MainThreadFunction(void*);
+
+ static PluginMainThreadScheduler& scheduler();
+
+ void scheduleCall(NPP, MainThreadFunction*, void* userData);
+
+ void registerPlugin(NPP);
+ void unregisterPlugin(NPP);
+
+private:
+ PluginMainThreadScheduler();
+ void dispatchCalls();
+
+ class Call;
+
+ void dispatchCallsForPlugin(NPP, const Deque<Call>& calls);
+ typedef HashMap<NPP, Deque<Call> > CallQueueMap;
+
+ static void mainThreadCallback(void* context);
+
+ class Call {
+ public:
+ Call(MainThreadFunction* function, void* userData)
+ : m_function(function)
+ , m_userData(userData)
+ {
+ }
+
+ void performCall() const
+ {
+ m_function(m_userData);
+ }
+
+ private:
+ MainThreadFunction* m_function;
+ void* m_userData;
+ };
+
+ bool m_callPending;
+ CallQueueMap m_callQueueMap;
+ Mutex m_queueMutex;
+};
+
+} // namespace WebCore
+
+#endif // PluginMainThreadScheduler_h
diff --git a/WebCore/plugins/PluginPackage.cpp b/WebCore/plugins/PluginPackage.cpp
new file mode 100644
index 0000000..f3c9075
--- /dev/null
+++ b/WebCore/plugins/PluginPackage.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginPackage.h"
+
+#include "CString.h"
+#include "MIMETypeRegistry.h"
+#include "PluginDatabase.h"
+#include "PluginDebug.h"
+#include "Timer.h"
+#include "npruntime_impl.h"
+#include <string.h>
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+PluginPackage::~PluginPackage()
+{
+ // This destructor gets called during refresh() if PluginDatabase's
+ // PluginSet hash is already populated, as it removes items from
+ // the hash table. Calling the destructor on a loaded plug-in of
+ // course would cause a crash, so we check to call unload before we
+ // ASSERT.
+ // FIXME: There is probably a better way to fix this.
+ if (m_loadCount == 0)
+ unloadWithoutShutdown();
+ else
+ unload();
+
+ ASSERT(!m_isLoaded);
+}
+
+void PluginPackage::freeLibrarySoon()
+{
+ ASSERT(!m_freeLibraryTimer.isActive());
+ ASSERT(m_module);
+ ASSERT(m_loadCount == 0);
+
+#ifdef ANDROID_PLUGINS
+ // TODO(jripley): Timer<T> is broken. Unload immediately for now.
+ unloadModule(m_module);
+ m_module = 0;
+#else
+ m_freeLibraryTimer.startOneShot(0);
+#endif
+}
+
+void PluginPackage::freeLibraryTimerFired(Timer<PluginPackage>*)
+{
+ ASSERT(m_module);
+ ASSERT(m_loadCount == 0);
+
+ unloadModule(m_module);
+ m_module = 0;
+}
+
+
+int PluginPackage::compare(const PluginPackage& compareTo) const
+{
+ // Sort plug-ins that allow multiple instances first.
+ bool AallowsMultipleInstances = !quirks().contains(PluginQuirkDontAllowMultipleInstances);
+ bool BallowsMultipleInstances = !compareTo.quirks().contains(PluginQuirkDontAllowMultipleInstances);
+ if (AallowsMultipleInstances != BallowsMultipleInstances)
+ return AallowsMultipleInstances ? -1 : 1;
+
+ // Sort plug-ins in a preferred path first.
+ bool AisInPreferredDirectory = PluginDatabase::isPreferredPluginDirectory(parentDirectory());
+ bool BisInPreferredDirectory = PluginDatabase::isPreferredPluginDirectory(compareTo.parentDirectory());
+ if (AisInPreferredDirectory != BisInPreferredDirectory)
+ return AisInPreferredDirectory ? -1 : 1;
+
+ int diff = strcmp(name().utf8().data(), compareTo.name().utf8().data());
+ if (diff)
+ return diff;
+
+ if (diff = compareFileVersion(compareTo.version()))
+ return diff;
+
+ return strcmp(parentDirectory().utf8().data(), compareTo.parentDirectory().utf8().data());
+}
+
+PluginPackage::PluginPackage(const String& path, const time_t& lastModified)
+ : m_isLoaded(false)
+ , m_loadCount(0)
+ , m_path(path)
+ , m_moduleVersion(0)
+ , m_module(0)
+ , m_lastModified(lastModified)
+ , m_freeLibraryTimer(this, &PluginPackage::freeLibraryTimerFired)
+{
+ m_fileName = pathGetFileName(m_path);
+ m_parentDirectory = m_path.left(m_path.length() - m_fileName.length() - 1);
+}
+
+void PluginPackage::unload()
+{
+ if (!m_isLoaded)
+ return;
+
+ if (--m_loadCount > 0)
+ return;
+
+ m_NPP_Shutdown();
+
+ unloadWithoutShutdown();
+}
+
+void PluginPackage::unloadWithoutShutdown()
+{
+ if (!m_isLoaded)
+ return;
+
+ ASSERT(m_loadCount == 0);
+ ASSERT(m_module);
+
+#if defined(ANDROID_PLUGINS)
+ // Remove the Java object from PluginList.
+ unregisterPluginObject();
+#endif
+
+ // <rdar://5530519>: Crash when closing tab with pdf file (Reader 7 only)
+ // If the plugin has subclassed its parent window, as with Reader 7, we may have
+ // gotten here by way of the plugin's internal window proc forwarding a message to our
+ // original window proc. If we free the plugin library from here, we will jump back
+ // to code we just freed when we return, so delay calling FreeLibrary at least until
+ // the next message loop
+ freeLibrarySoon();
+
+ m_isLoaded = false;
+}
+
+PassRefPtr<PluginPackage> PluginPackage::createPackage(const String& path, const time_t& lastModified)
+{
+ RefPtr<PluginPackage> package = adoptRef(new PluginPackage(path, lastModified));
+
+ if (!package->fetchInfo())
+ return 0;
+
+ return package.release();
+}
+
+}
diff --git a/WebCore/plugins/PluginPackage.h b/WebCore/plugins/PluginPackage.h
index ab15e33..4cf5e9e 100644
--- a/WebCore/plugins/PluginPackage.h
+++ b/WebCore/plugins/PluginPackage.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,25 +27,17 @@
#ifndef PluginPackage_H
#define PluginPackage_H
-#ifdef ANDROID_PLUGINS
-
-#include "PluginPackageAndroid.h"
-
-namespace WebCore {
- typedef PluginPackageAndroid PluginPackage;
-}
-
-#else !defined(ANDROID_PLUGINS)
-
-#include <winsock2.h>
-#include <windows.h>
-
-#include "Timer.h"
-#include "StringHash.h"
+#include "FileSystem.h"
#include "PlatformString.h"
-#include "npfunctions.h"
+#include "PluginQuirkSet.h"
+#include "StringHash.h"
+#include "Timer.h"
+#include "npruntime_internal.h"
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
+#if defined(ANDROID_PLUGINS)
+#include <nativehelper/jni.h>
+#endif
namespace WebCore {
typedef HashMap<String, String> MIMEToDescriptionsMap;
@@ -53,17 +46,19 @@ namespace WebCore {
class PluginPackage : public RefCounted<PluginPackage> {
public:
~PluginPackage();
- static PluginPackage* createPackage(const String& path, const FILETIME& lastModified);
+ static PassRefPtr<PluginPackage> createPackage(const String& path, const time_t& lastModified);
- String name() const { return m_name; }
- String description() const { return m_description; }
- String fileName() const { return m_fileName; }
- String parentDirectory() const { return m_parentDirectory; }
+ const String& name() const { return m_name; }
+ const String& description() const { return m_description; }
+ const String& path() const { return m_path; }
+ const String& fileName() const { return m_fileName; }
+ const String& parentDirectory() const { return m_parentDirectory; }
+ time_t lastModified() const { return m_lastModified; }
const MIMEToDescriptionsMap& mimeToDescriptions() const { return m_mimeToDescriptions; }
const MIMEToExtensionsMap& mimeToExtensions() const { return m_mimeToExtensions; }
- unsigned PluginPackage::hash() const;
+ unsigned hash() const;
static bool equal(const PluginPackage& a, const PluginPackage& b);
bool load();
@@ -71,31 +66,33 @@ namespace WebCore {
void unloadWithoutShutdown();
const NPPluginFuncs* pluginFuncs() const { return &m_pluginFuncs; }
+ int compareFileVersion(const PlatformModuleVersion&) const;
+ int compare(const PluginPackage&) const;
+ PluginQuirkSet quirks() const { return m_quirks; }
+ const PlatformModuleVersion& version() const { return m_moduleVersion; }
- int compareFileVersion(unsigned compareVersionMS, unsigned compareVersionLS) const;
private:
- PluginPackage(const String& path, const FILETIME& lastModified);
+ PluginPackage(const String& path, const time_t& lastModified);
bool fetchInfo();
- void storeFileVersion(LPVOID versionInfoData);
bool isPluginBlacklisted();
+ void determineQuirks(const String& mimeType);
bool m_isLoaded;
int m_loadCount;
- DWORD m_fileVersionMS;
- DWORD m_fileVersionLS;
-
String m_description;
String m_path;
String m_fileName;
String m_name;
String m_parentDirectory;
+ PlatformModuleVersion m_moduleVersion;
+
MIMEToDescriptionsMap m_mimeToDescriptions;
MIMEToExtensionsMap m_mimeToExtensions;
- HMODULE m_module;
- FILETIME m_lastModified;
+ PlatformModule m_module;
+ time_t m_lastModified;
NPP_ShutdownProcPtr m_NPP_Shutdown;
NPPluginFuncs m_pluginFuncs;
@@ -104,29 +101,27 @@ namespace WebCore {
void freeLibrarySoon();
void freeLibraryTimerFired(Timer<PluginPackage>*);
Timer<PluginPackage> m_freeLibraryTimer;
+
+ PluginQuirkSet m_quirks;
+
+#if defined(ANDROID_PLUGINS)
+ // Java Plugin object.
+ jobject m_pluginObject;
+ // Called from unloadWithoutShutdown() to remove the object
+ // from the PluginList.
+ void unregisterPluginObject();
+#endif
};
struct PluginPackageHash {
- static unsigned hash(const int key) { return reinterpret_cast<PluginPackage*>(key)->hash(); }
+ static unsigned hash(const uintptr_t key) { return reinterpret_cast<PluginPackage*>(key)->hash(); }
static unsigned hash(const RefPtr<PluginPackage>& key) { return key->hash(); }
- static bool equal(const int a, const int b) { return equal(reinterpret_cast<PluginPackage*>(a), reinterpret_cast<PluginPackage*>(b)); }
+ static bool equal(const uintptr_t a, const uintptr_t b) { return equal(reinterpret_cast<PluginPackage*>(a), reinterpret_cast<PluginPackage*>(b)); }
static bool equal(const RefPtr<PluginPackage>& a, const RefPtr<PluginPackage>& b) { return PluginPackage::equal(*a.get(), *b.get()); }
static const bool safeToCompareToEmptyOrDeleted = false;
};
} // namespace WebCore
-// FIXME: This is a workaround for a bug in WTF, where it's impossible to use a custom Hash function but with default traits.
-// It should be possible to do this without a StorageTraits specialization.
-namespace WTF {
- template<> struct HashKeyStorageTraits<WebCore::PluginPackageHash, HashTraits<RefPtr<WebCore::PluginPackage> > > {
- typedef IntTypes<sizeof(RefPtr<WebCore::PluginPackage>)>::SignedType IntType;
- typedef WebCore::PluginPackageHash Hash;
- typedef HashTraits<IntType> Traits;
- };
-}
-
-#endif // !defined(ANDROID_PLUGINS)
-
#endif
diff --git a/WebCore/plugins/PluginQuirkSet.h b/WebCore/plugins/PluginQuirkSet.h
index 031baa0..e93f6e0 100644
--- a/WebCore/plugins/PluginQuirkSet.h
+++ b/WebCore/plugins/PluginQuirkSet.h
@@ -44,6 +44,7 @@ namespace WebCore {
PluginQuirkFlashURLNotifyBug = 1 << 8,
PluginQuirkDontClipToZeroRectWhenScrolling = 1 << 9,
PluginQuirkDontSetNullWindowHandleOnDestroy = 1 << 10,
+ PluginQuirkDontAllowMultipleInstances = 1 << 11,
};
class PluginQuirkSet {
diff --git a/WebCore/plugins/PluginStream.cpp b/WebCore/plugins/PluginStream.cpp
index a206b51..4bf2db4 100644
--- a/WebCore/plugins/PluginStream.cpp
+++ b/WebCore/plugins/PluginStream.cpp
@@ -129,14 +129,10 @@ void PluginStream::startStream()
// Some plugins (Flash) expect that javascript URLs are passed back decoded as this is the
// format used when requesting the URL.
-#ifdef ANDROID_JAVASCRIPT_SECURITY
if (responseURL.protocolIs("javascript"))
-#else
- if (responseURL.string().startsWith("javascript:", false))
-#endif
- m_stream.url = strdup(responseURL.decode_string(responseURL.deprecatedString()).utf8());
+ m_stream.url = strdup(decodeURLEscapeSequences(responseURL.string()).utf8().data());
else
- m_stream.url = strdup(responseURL.deprecatedString().utf8());
+ m_stream.url = strdup(responseURL.string().utf8().data());
CString mimeTypeStr = m_resourceResponse.mimeType().utf8();
@@ -146,12 +142,16 @@ void PluginStream::startStream()
Vector<UChar> stringBuilder;
String separator(": ");
+ String statusLine = String::format("HTTP %lu OK\n", m_resourceResponse.httpStatusCode());
+
+ stringBuilder.append(statusLine.characters(), statusLine.length());
+
HTTPHeaderMap::const_iterator end = m_resourceResponse.httpHeaderFields().end();
for (HTTPHeaderMap::const_iterator it = m_resourceResponse.httpHeaderFields().begin(); it != end; ++it) {
stringBuilder.append(it->first.characters(), it->first.length());
stringBuilder.append(separator.characters(), separator.length());
stringBuilder.append(it->second.characters(), it->second.length());
- stringBuilder.append((UChar)'\n');
+ stringBuilder.append('\n');
}
m_headers = String::adopt(stringBuilder).utf8();
@@ -191,10 +191,12 @@ void PluginStream::startStream()
if (m_reason != WebReasonNone)
return;
- m_streamState = StreamStarted;
-
- if (npErr != NPERR_NO_ERROR)
+ if (npErr != NPERR_NO_ERROR) {
cancelAndDestroyStream(npErr);
+ return;
+ }
+
+ m_streamState = StreamStarted;
if (m_transferMode == NP_NORMAL)
return;
@@ -238,8 +240,8 @@ void PluginStream::destroyStream()
if (m_streamState == StreamStopped)
return;
- ASSERT (m_reason != WebReasonNone);
- ASSERT (!m_deliveryData || m_deliveryData->size() == 0);
+ ASSERT(m_reason != WebReasonNone);
+ ASSERT(!m_deliveryData || m_deliveryData->size() == 0);
closeFile(m_tempFileHandle);
@@ -256,12 +258,17 @@ void PluginStream::destroyStream()
m_loader->setDefersLoading(false);
}
- if (m_loader)
- m_loader->setDefersLoading(true);
- NPError npErr = m_pluginFuncs->destroystream(m_instance, &m_stream, m_reason);
- if (m_loader)
- m_loader->setDefersLoading(false);
- LOG_NPERROR(npErr);
+ if (m_streamState != StreamBeforeStarted) {
+ if (m_loader)
+ m_loader->setDefersLoading(true);
+
+ NPError npErr = m_pluginFuncs->destroystream(m_instance, &m_stream, m_reason);
+
+ if (m_loader)
+ m_loader->setDefersLoading(false);
+
+ LOG_NPERROR(npErr);
+ }
m_stream.ndata = 0;
}
@@ -287,7 +294,7 @@ void PluginStream::destroyStream()
// destructor, so reset it to 0
m_stream.url = 0;
}
- m_pluginFuncs->urlnotify(m_instance, m_resourceRequest.url().deprecatedString().utf8(), m_reason, m_notifyData);
+ m_pluginFuncs->urlnotify(m_instance, m_resourceRequest.url().string().utf8().data(), m_reason, m_notifyData);
if (m_loader)
m_loader->setDefersLoading(false);
}
@@ -452,4 +459,16 @@ void PluginStream::didFinishLoading(NetscapePlugInStreamLoader* loader)
m_loader = 0;
}
+bool PluginStream::wantsAllStreams() const
+{
+ if (!m_pluginFuncs->getvalue)
+ return false;
+
+ void* result = 0;
+ if (m_pluginFuncs->getvalue(m_instance, NPPVpluginWantsAllNetworkStreams, &result) != NPERR_NO_ERROR)
+ return false;
+
+ return result != 0;
+}
+
}
diff --git a/WebCore/plugins/PluginStream.h b/WebCore/plugins/PluginStream.h
index 6eb7b81..dc08f01 100644
--- a/WebCore/plugins/PluginStream.h
+++ b/WebCore/plugins/PluginStream.h
@@ -27,20 +27,9 @@
#ifndef PluginStream_H
#define PluginStream_H
-#ifdef ANDROID_PLUGINS
-
-#include "PluginStreamAndroid.h"
-
-namespace WebCore {
- typedef PluginStreamAndroid PluginStream;
-}
-
-#else // !defined(ANDROID_PLUGINS)
-
#include "CString.h"
#include "FileSystem.h"
#include "KURL.h"
-#include "npfunctions.h"
#include "NetscapePlugInStreamLoader.h"
#include "PlatformString.h"
#include "PluginQuirkSet.h"
@@ -48,10 +37,11 @@ namespace WebCore {
#include "ResourceResponse.h"
#include "StringHash.h"
#include "Timer.h"
+#include "npruntime_internal.h"
#include <wtf/HashMap.h>
-#include <wtf/Vector.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
namespace WebCore {
class Frame;
@@ -67,8 +57,11 @@ namespace WebCore {
class PluginStream : public RefCounted<PluginStream>, private NetscapePlugInStreamLoaderClient {
public:
- PluginStream(PluginStreamClient*, Frame*, const ResourceRequest&, bool sendNotification, void* notifyData, const NPPluginFuncs*, NPP instance, const PluginQuirkSet&);
- ~PluginStream();
+ static PassRefPtr<PluginStream> create(PluginStreamClient* client, Frame* frame, const ResourceRequest& request, bool sendNotification, void* notifyData, const NPPluginFuncs* functions, NPP instance, const PluginQuirkSet& quirks)
+ {
+ return adoptRef(new PluginStream(client, frame, request, sendNotification, notifyData, functions, instance, quirks));
+ }
+ virtual ~PluginStream();
void start();
void stop();
@@ -77,17 +70,21 @@ namespace WebCore {
void setLoadManually(bool loadManually) { m_loadManually = loadManually; }
+ void sendJavaScriptStream(const KURL& requestURL, const CString& resultString);
+ void cancelAndDestroyStream(NPReason);
+
+ static NPP ownerForStream(NPStream*);
+
// NetscapePlugInStreamLoaderClient
virtual void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&);
virtual void didReceiveData(NetscapePlugInStreamLoader*, const char*, int);
virtual void didFail(NetscapePlugInStreamLoader*, const ResourceError&);
virtual void didFinishLoading(NetscapePlugInStreamLoader*);
+ virtual bool wantsAllStreams() const;
- void sendJavaScriptStream(const KURL& requestURL, const CString& resultString);
- void cancelAndDestroyStream(NPReason);
-
- static NPP ownerForStream(NPStream*);
private:
+ PluginStream(PluginStreamClient*, Frame*, const ResourceRequest&, bool sendNotification, void* notifyData, const NPPluginFuncs*, NPP instance, const PluginQuirkSet&);
+
void deliverData();
void destroyStream(NPReason);
void destroyStream();
@@ -123,6 +120,4 @@ namespace WebCore {
} // namespace WebCore
-#endif // !defined(ANDROID_PLUGINS)
-
#endif
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
new file mode 100644
index 0000000..459b11e
--- /dev/null
+++ b/WebCore/plugins/PluginView.cpp
@@ -0,0 +1,922 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginView.h"
+
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "Element.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "HTMLNames.h"
+#include "HTMLPlugInElement.h"
+#include "JSDOMWindow.h"
+#include "KeyboardEvent.h"
+#include "MIMETypeRegistry.h"
+#include "MouseEvent.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "FocusController.h"
+#include "PlatformMouseEvent.h"
+#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
+#include "PluginMessageThrottlerWin.h"
+#endif
+#include "PluginPackage.h"
+#include "JSDOMBinding.h"
+#include "ScriptController.h"
+#include "PluginDatabase.h"
+#include "PluginDebug.h"
+#include "PluginMainThreadScheduler.h"
+#include "PluginPackage.h"
+#include "RenderObject.h"
+#include "c_instance.h"
+#include "npruntime_impl.h"
+#include "runtime_root.h"
+#include "Settings.h"
+#include "runtime.h"
+#include <runtime/JSLock.h>
+#include <runtime/JSValue.h>
+#include <wtf/ASCIICType.h>
+
+using JSC::ExecState;
+using JSC::JSLock;
+using JSC::JSObject;
+using JSC::JSValue;
+using JSC::UString;
+
+using std::min;
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static int s_callingPlugin;
+
+static String scriptStringIfJavaScriptURL(const KURL& url)
+{
+ if (!url.protocolIs("javascript"))
+ return String();
+
+ // This returns an unescaped string
+ return decodeURLEscapeSequences(url.string().substring(11));
+}
+
+PluginView* PluginView::s_currentPluginView = 0;
+
+void PluginView::popPopupsStateTimerFired(Timer<PluginView>*)
+{
+ popPopupsEnabledState();
+}
+
+IntRect PluginView::windowClipRect() const
+{
+ // Start by clipping to our bounds.
+ IntRect clipRect(m_windowRect);
+
+ // Take our element and get the clip rect from the enclosing layer and frame view.
+ RenderLayer* layer = m_element->renderer()->enclosingLayer();
+ FrameView* parentView = m_element->document()->view();
+ clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
+
+ return clipRect;
+}
+
+void PluginView::setFrameRect(const IntRect& rect)
+{
+ if (m_element->document()->printing())
+ return;
+
+#if defined(ANDROID_PLUGINS)
+ if (rect != frameRect()) {
+ Widget::setFrameRect(rect);
+ setNPWindowRect(rect); // only call when it changes
+ }
+#else
+ if (rect != frameRect())
+ Widget::setFrameRect(rect);
+#endif
+
+ updatePluginWidget();
+
+#if PLATFORM(WIN_OS)
+ // On Windows, always call plugin to change geometry.
+ setNPWindowRect(rect);
+#elif XP_UNIX
+ // On Unix, only call plugin if it's full-page.
+ if (m_mode == NP_FULL)
+ setNPWindowRect(rect);
+#endif
+}
+
+void PluginView::frameRectsChanged() const
+{
+ updatePluginWidget();
+}
+
+void PluginView::handleEvent(Event* event)
+{
+ if (!m_plugin || m_isWindowed)
+ return;
+
+ if (event->isMouseEvent())
+ handleMouseEvent(static_cast<MouseEvent*>(event));
+ else if (event->isKeyboardEvent())
+ handleKeyboardEvent(static_cast<KeyboardEvent*>(event));
+}
+
+bool PluginView::start()
+{
+ if (m_isStarted)
+ return false;
+
+ PluginMainThreadScheduler::scheduler().registerPlugin(m_instance);
+
+ ASSERT(m_plugin);
+ ASSERT(m_plugin->pluginFuncs()->newp);
+
+ NPError npErr;
+ {
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ npErr = m_plugin->pluginFuncs()->newp((NPMIMEType)m_mimeType.data(), m_instance, m_mode, m_paramCount, m_paramNames, m_paramValues, NULL);
+ setCallingPlugin(false);
+ LOG_NPERROR(npErr);
+ PluginView::setCurrentPluginView(0);
+ }
+
+ if (npErr != NPERR_NO_ERROR)
+ return false;
+
+ m_isStarted = true;
+
+ if (!m_url.isEmpty() && !m_loadManually) {
+ FrameLoadRequest frameLoadRequest;
+ frameLoadRequest.resourceRequest().setHTTPMethod("GET");
+ frameLoadRequest.resourceRequest().setURL(m_url);
+ load(frameLoadRequest, false, 0);
+ }
+
+ return true;
+}
+
+void PluginView::setCurrentPluginView(PluginView* pluginView)
+{
+ s_currentPluginView = pluginView;
+}
+
+PluginView* PluginView::currentPluginView()
+{
+ return s_currentPluginView;
+}
+
+static char* createUTF8String(const String& str)
+{
+ CString cstr = str.utf8();
+ char* result = reinterpret_cast<char*>(fastMalloc(cstr.length() + 1));
+
+ strncpy(result, cstr.data(), cstr.length() + 1);
+
+ return result;
+}
+
+static bool getString(ScriptController* proxy, JSValue* result, String& string)
+{
+ if (!proxy || !result || result->isUndefined())
+ return false;
+ JSLock lock(false);
+
+ ExecState* exec = proxy->globalObject()->globalExec();
+ UString ustring = result->toString(exec);
+ exec->clearException();
+
+ string = ustring;
+ return true;
+}
+
+void PluginView::performRequest(PluginRequest* request)
+{
+ // don't let a plugin start any loads if it is no longer part of a document that is being
+ // displayed unless the loads are in the same frame as the plugin.
+ const String& targetFrameName = request->frameLoadRequest().frameName();
+ if (m_parentFrame->loader()->documentLoader() != m_parentFrame->loader()->activeDocumentLoader() &&
+ (targetFrameName.isNull() || m_parentFrame->tree()->find(targetFrameName) != m_parentFrame))
+ return;
+
+ KURL requestURL = request->frameLoadRequest().resourceRequest().url();
+ String jsString = scriptStringIfJavaScriptURL(requestURL);
+
+ if (jsString.isNull()) {
+ // if this is not a targeted request, create a stream for it. otherwise,
+ // just pass it off to the loader
+ if (targetFrameName.isEmpty()) {
+ RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ m_streams.add(stream);
+ stream->start();
+ } else {
+ m_parentFrame->loader()->load(request->frameLoadRequest().resourceRequest(), targetFrameName);
+
+ // FIXME: <rdar://problem/4807469> This should be sent when the document has finished loading
+ if (request->sendNotification()) {
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->urlnotify(m_instance, requestURL.string().utf8().data(), NPRES_DONE, request->notifyData());
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+ }
+ return;
+ }
+
+ // Targeted JavaScript requests are only allowed on the frame that contains the JavaScript plugin
+ // and this has been made sure in ::load.
+ ASSERT(targetFrameName.isEmpty() || m_parentFrame->tree()->find(targetFrameName) == m_parentFrame);
+
+ // Executing a script can cause the plugin view to be destroyed, so we keep a reference to the parent frame.
+ RefPtr<Frame> parentFrame = m_parentFrame;
+ JSValue* result = m_parentFrame->loader()->executeScript(jsString, request->shouldAllowPopups());
+
+ if (targetFrameName.isNull()) {
+ String resultString;
+
+ CString cstr;
+ if (getString(parentFrame->script(), result, resultString))
+ cstr = resultString.utf8();
+
+ RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ m_streams.add(stream);
+ stream->sendJavaScriptStream(requestURL, cstr);
+ }
+}
+
+void PluginView::requestTimerFired(Timer<PluginView>* timer)
+{
+ ASSERT(timer == &m_requestTimer);
+ ASSERT(m_requests.size() > 0);
+ ASSERT(!m_isJavaScriptPaused);
+
+ PluginRequest* request = m_requests[0];
+ m_requests.remove(0);
+
+ // Schedule a new request before calling performRequest since the call to
+ // performRequest can cause the plugin view to be deleted.
+ if (m_requests.size() > 0)
+ m_requestTimer.startOneShot(0);
+
+ performRequest(request);
+ delete request;
+}
+
+void PluginView::scheduleRequest(PluginRequest* request)
+{
+ m_requests.append(request);
+
+ if (!m_isJavaScriptPaused)
+ m_requestTimer.startOneShot(0);
+}
+
+NPError PluginView::load(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData)
+{
+ ASSERT(frameLoadRequest.resourceRequest().httpMethod() == "GET" || frameLoadRequest.resourceRequest().httpMethod() == "POST");
+
+ KURL url = frameLoadRequest.resourceRequest().url();
+
+ if (url.isEmpty())
+ return NPERR_INVALID_URL;
+
+ // Don't allow requests to be made when the document loader is stopping all loaders.
+ if (m_parentFrame->loader()->documentLoader()->isStopping())
+ return NPERR_GENERIC_ERROR;
+
+ const String& targetFrameName = frameLoadRequest.frameName();
+ String jsString = scriptStringIfJavaScriptURL(url);
+
+ if (!jsString.isNull()) {
+ Settings* settings = m_parentFrame->settings();
+
+ // Return NPERR_GENERIC_ERROR if JS is disabled. This is what Mozilla does.
+ if (!settings || !settings->isJavaScriptEnabled())
+ return NPERR_GENERIC_ERROR;
+
+ // For security reasons, only allow JS requests to be made on the frame that contains the plug-in.
+ if (!targetFrameName.isNull() && m_parentFrame->tree()->find(targetFrameName) != m_parentFrame)
+ return NPERR_INVALID_PARAM;
+ } else if (!FrameLoader::canLoad(url, String(), m_parentFrame->document())) {
+ return NPERR_GENERIC_ERROR;
+ }
+
+ PluginRequest* request = new PluginRequest(frameLoadRequest, sendNotification, notifyData, arePopupsAllowed());
+ scheduleRequest(request);
+
+ return NPERR_NO_ERROR;
+}
+
+static KURL makeURL(const KURL& baseURL, const char* relativeURLString)
+{
+ String urlString = relativeURLString;
+
+ // Strip return characters.
+ urlString.replace('\n', "");
+ urlString.replace('\r', "");
+
+ return KURL(baseURL, urlString);
+}
+
+NPError PluginView::getURLNotify(const char* url, const char* target, void* notifyData)
+{
+ FrameLoadRequest frameLoadRequest;
+
+ frameLoadRequest.setFrameName(target);
+ frameLoadRequest.resourceRequest().setHTTPMethod("GET");
+ frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url));
+
+ return load(frameLoadRequest, true, notifyData);
+}
+
+NPError PluginView::getURL(const char* url, const char* target)
+{
+ FrameLoadRequest frameLoadRequest;
+
+ frameLoadRequest.setFrameName(target);
+ frameLoadRequest.resourceRequest().setHTTPMethod("GET");
+ frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url));
+
+ return load(frameLoadRequest, false, 0);
+}
+
+NPError PluginView::postURLNotify(const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData)
+{
+ return handlePost(url, target, len, buf, file, notifyData, true, true);
+}
+
+NPError PluginView::postURL(const char* url, const char* target, uint32 len, const char* buf, NPBool file)
+{
+ // As documented, only allow headers to be specified via NPP_PostURL when using a file.
+ return handlePost(url, target, len, buf, file, 0, false, file);
+}
+
+NPError PluginView::newStream(NPMIMEType type, const char* target, NPStream** stream)
+{
+ notImplemented();
+ // Unsupported
+ return NPERR_GENERIC_ERROR;
+}
+
+int32 PluginView::write(NPStream* stream, int32 len, void* buffer)
+{
+ notImplemented();
+ // Unsupported
+ return -1;
+}
+
+NPError PluginView::destroyStream(NPStream* stream, NPReason reason)
+{
+ PluginStream* browserStream = static_cast<PluginStream*>(stream->ndata);
+
+ if (!stream || PluginStream::ownerForStream(stream) != m_instance)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ browserStream->cancelAndDestroyStream(reason);
+ return NPERR_NO_ERROR;
+}
+
+void PluginView::status(const char* message)
+{
+ if (Page* page = m_parentFrame->page())
+ page->chrome()->setStatusbarText(m_parentFrame, String(message));
+}
+
+NPError PluginView::setValue(NPPVariable variable, void* value)
+{
+ switch (variable) {
+ case NPPVpluginWindowBool:
+ m_isWindowed = value;
+ return NPERR_NO_ERROR;
+ case NPPVpluginTransparentBool:
+ m_isTransparent = value;
+ return NPERR_NO_ERROR;
+ default:
+#ifdef PLUGIN_PLATFORM_SETVALUE
+ return platformSetValue(variable, value);
+#else
+ notImplemented();
+ return NPERR_GENERIC_ERROR;
+#endif
+ }
+}
+
+void PluginView::invalidateTimerFired(Timer<PluginView>* timer)
+{
+ ASSERT(timer == &m_invalidateTimer);
+
+ for (unsigned i = 0; i < m_invalidRects.size(); i++)
+ invalidateRect(m_invalidRects[i]);
+ m_invalidRects.clear();
+}
+
+
+void PluginView::pushPopupsEnabledState(bool state)
+{
+ m_popupStateStack.append(state);
+}
+
+void PluginView::popPopupsEnabledState()
+{
+ m_popupStateStack.removeLast();
+}
+
+bool PluginView::arePopupsAllowed() const
+{
+ if (!m_popupStateStack.isEmpty())
+ return m_popupStateStack.last();
+
+ return false;
+}
+
+void PluginView::setJavaScriptPaused(bool paused)
+{
+ if (m_isJavaScriptPaused == paused)
+ return;
+ m_isJavaScriptPaused = paused;
+
+ if (m_isJavaScriptPaused)
+ m_requestTimer.stop();
+ else if (!m_requests.isEmpty())
+ m_requestTimer.startOneShot(0);
+}
+
+PassRefPtr<JSC::Bindings::Instance> PluginView::bindingInstance()
+{
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ NPObject* object = 0;
+
+ if (!m_plugin || !m_plugin->pluginFuncs()->getvalue)
+ return 0;
+
+ NPError npErr;
+ {
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ npErr = m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginScriptableNPObject, &object);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+
+ if (npErr != NPERR_NO_ERROR || !object)
+ return 0;
+
+ RefPtr<JSC::Bindings::RootObject> root = m_parentFrame->script()->createRootObject(this);
+ RefPtr<JSC::Bindings::Instance> instance = JSC::Bindings::CInstance::create(object, root.release());
+
+ _NPN_ReleaseObject(object);
+
+ return instance.release();
+#else
+ return 0;
+#endif
+}
+
+void PluginView::disconnectStream(PluginStream* stream)
+{
+ ASSERT(m_streams.contains(stream));
+
+ m_streams.remove(stream);
+}
+
+void PluginView::setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues)
+{
+ ASSERT(paramNames.size() == paramValues.size());
+
+ unsigned size = paramNames.size();
+ unsigned paramCount = 0;
+
+ m_paramNames = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size));
+ m_paramValues = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size));
+
+ for (unsigned i = 0; i < size; i++) {
+ if (m_plugin->quirks().contains(PluginQuirkRemoveWindowlessVideoParam) && equalIgnoringCase(paramNames[i], "windowlessvideo"))
+ continue;
+
+ m_paramNames[paramCount] = createUTF8String(paramNames[i]);
+ m_paramValues[paramCount] = createUTF8String(paramValues[i]);
+
+ paramCount++;
+ }
+
+ m_paramCount = paramCount;
+}
+
+PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* plugin, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
+ : m_parentFrame(parentFrame)
+ , m_plugin(plugin)
+ , m_element(element)
+ , m_isStarted(false)
+ , m_url(url)
+ , m_baseURL(m_parentFrame->loader()->completeURL(m_parentFrame->document()->baseURL().string()))
+ , m_status(PluginStatusLoadedSuccessfully)
+ , m_requestTimer(this, &PluginView::requestTimerFired)
+ , m_invalidateTimer(this, &PluginView::invalidateTimerFired)
+ , m_popPopupsStateTimer(this, &PluginView::popPopupsStateTimerFired)
+ , m_paramNames(0)
+ , m_paramValues(0)
+ , m_isWindowed(true)
+ , m_isTransparent(false)
+ , m_haveInitialized(false)
+#if PLATFORM(GTK) || defined(Q_WS_X11)
+ , m_needsXEmbed(false)
+#endif
+#if PLATFORM(QT)
+ , m_isNPAPIPlugin(false)
+#endif
+#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
+ , m_pluginWndProc(0)
+ , m_lastMessage(0)
+ , m_isCallingPluginWndProc(false)
+#endif
+#if PLATFORM(WIN_OS) && PLATFORM(QT)
+ , m_window(0)
+#endif
+ , m_loadManually(loadManually)
+ , m_manualStream(0)
+ , m_isJavaScriptPaused(false)
+{
+#if defined(ANDROID_PLUGINS)
+ platformInit();
+#endif
+
+ if (!m_plugin) {
+ m_status = PluginStatusCanNotFindPlugin;
+ return;
+ }
+
+ m_instance = &m_instanceStruct;
+ m_instance->ndata = this;
+ m_instance->pdata = 0;
+
+ m_mimeType = mimeType.utf8();
+
+ setParameters(paramNames, paramValues);
+
+#ifdef XP_UNIX
+ m_npWindow.ws_info = 0;
+#endif
+
+ m_mode = m_loadManually ? NP_FULL : NP_EMBED;
+
+ resize(size);
+}
+
+void PluginView::didReceiveResponse(const ResourceResponse& response)
+{
+ ASSERT(m_loadManually);
+ ASSERT(!m_manualStream);
+
+ m_manualStream = PluginStream::create(this, m_parentFrame, m_parentFrame->loader()->activeDocumentLoader()->request(), false, 0, plugin()->pluginFuncs(), instance(), m_plugin->quirks());
+ m_manualStream->setLoadManually(true);
+
+ m_manualStream->didReceiveResponse(0, response);
+}
+
+void PluginView::didReceiveData(const char* data, int length)
+{
+ ASSERT(m_loadManually);
+ ASSERT(m_manualStream);
+
+ m_manualStream->didReceiveData(0, data, length);
+}
+
+void PluginView::didFinishLoading()
+{
+ ASSERT(m_loadManually);
+ ASSERT(m_manualStream);
+
+ m_manualStream->didFinishLoading(0);
+}
+
+void PluginView::didFail(const ResourceError& error)
+{
+ ASSERT(m_loadManually);
+ ASSERT(m_manualStream);
+
+ m_manualStream->didFail(0, error);
+}
+
+void PluginView::setCallingPlugin(bool b) const
+{
+ if (!m_plugin->quirks().contains(PluginQuirkHasModalMessageLoop))
+ return;
+
+ if (b)
+ ++s_callingPlugin;
+ else
+ --s_callingPlugin;
+
+ ASSERT(s_callingPlugin >= 0);
+}
+
+bool PluginView::isCallingPlugin()
+{
+ return s_callingPlugin > 0;
+}
+
+PluginView* PluginView::create(Frame* parentFrame, const IntSize& size, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
+{
+ // if we fail to find a plugin for this MIME type, findPlugin will search for
+ // a plugin by the file extension and update the MIME type, so pass a mutable String
+ String mimeTypeCopy = mimeType;
+ PluginPackage* plugin = PluginDatabase::installedPlugins()->findPlugin(url, mimeTypeCopy);
+
+ // No plugin was found, try refreshing the database and searching again
+ if (!plugin && PluginDatabase::installedPlugins()->refresh()) {
+ mimeTypeCopy = mimeType;
+ plugin = PluginDatabase::installedPlugins()->findPlugin(url, mimeTypeCopy);
+ }
+
+ return new PluginView(parentFrame, size, plugin, element, url, paramNames, paramValues, mimeTypeCopy, loadManually);
+}
+
+void PluginView::freeStringArray(char** stringArray, int length)
+{
+ if (!stringArray)
+ return;
+
+ for (int i = 0; i < length; i++)
+ fastFree(stringArray[i]);
+
+ fastFree(stringArray);
+}
+
+static inline bool startsWithBlankLine(const Vector<char>& buffer)
+{
+ return buffer.size() > 0 && buffer[0] == '\n';
+}
+
+static inline int locationAfterFirstBlankLine(const Vector<char>& buffer)
+{
+ const char* bytes = buffer.data();
+ unsigned length = buffer.size();
+
+ for (unsigned i = 0; i < length - 4; i++) {
+ // Support for Acrobat. It sends "\n\n".
+ if (bytes[i] == '\n' && bytes[i + 1] == '\n')
+ return i + 2;
+
+ // Returns the position after 2 CRLF's or 1 CRLF if it is the first line.
+ if (bytes[i] == '\r' && bytes[i + 1] == '\n') {
+ i += 2;
+ if (i == 2)
+ return i;
+ else if (bytes[i] == '\n')
+ // Support for Director. It sends "\r\n\n" (3880387).
+ return i + 1;
+ else if (bytes[i] == '\r' && bytes[i + 1] == '\n')
+ // Support for Flash. It sends "\r\n\r\n" (3758113).
+ return i + 2;
+ }
+ }
+
+ return -1;
+}
+
+static inline const char* findEOL(const char* bytes, unsigned length)
+{
+ // According to the HTTP specification EOL is defined as
+ // a CRLF pair. Unfortunately, some servers will use LF
+ // instead. Worse yet, some servers will use a combination
+ // of both (e.g. <header>CRLFLF<body>), so findEOL needs
+ // to be more forgiving. It will now accept CRLF, LF or
+ // CR.
+ //
+ // It returns NULL if EOLF is not found or it will return
+ // a pointer to the first terminating character.
+ for (unsigned i = 0; i < length; i++) {
+ if (bytes[i] == '\n')
+ return bytes + i;
+ if (bytes[i] == '\r') {
+ // Check to see if spanning buffer bounds
+ // (CRLF is across reads). If so, wait for
+ // next read.
+ if (i + 1 == length)
+ break;
+
+ return bytes + i;
+ }
+ }
+
+ return 0;
+}
+
+static inline String capitalizeRFC822HeaderFieldName(const String& name)
+{
+ bool capitalizeCharacter = true;
+ String result;
+
+ for (unsigned i = 0; i < name.length(); i++) {
+ UChar c;
+
+ if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z')
+ c = toASCIIUpper(name[i]);
+ else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z')
+ c = toASCIILower(name[i]);
+ else
+ c = name[i];
+
+ if (name[i] == '-')
+ capitalizeCharacter = true;
+ else
+ capitalizeCharacter = false;
+
+ result.append(c);
+ }
+
+ return result;
+}
+
+static inline HTTPHeaderMap parseRFC822HeaderFields(const Vector<char>& buffer, unsigned length)
+{
+ const char* bytes = buffer.data();
+ const char* eol;
+ String lastKey;
+ HTTPHeaderMap headerFields;
+
+ // Loop ove rlines until we're past the header, or we can't find any more end-of-lines
+ while ((eol = findEOL(bytes, length))) {
+ const char* line = bytes;
+ int lineLength = eol - bytes;
+
+ // Move bytes to the character after the terminator as returned by findEOL.
+ bytes = eol + 1;
+ if ((*eol == '\r') && (*bytes == '\n'))
+ bytes++; // Safe since findEOL won't return a spanning CRLF.
+
+ length -= (bytes - line);
+ if (lineLength == 0)
+ // Blank line; we're at the end of the header
+ break;
+ else if (*line == ' ' || *line == '\t') {
+ // Continuation of the previous header
+ if (lastKey.isNull()) {
+ // malformed header; ignore it and continue
+ continue;
+ } else {
+ // Merge the continuation of the previous header
+ String currentValue = headerFields.get(lastKey);
+ String newValue(line, lineLength);
+
+ headerFields.set(lastKey, currentValue + newValue);
+ }
+ } else {
+ // Brand new header
+ const char* colon;
+ for (colon = line; *colon != ':' && colon != eol; colon++) {
+ // empty loop
+ }
+ if (colon == eol)
+ // malformed header; ignore it and continue
+ continue;
+ else {
+ lastKey = capitalizeRFC822HeaderFieldName(String(line, colon - line));
+ String value;
+
+ for (colon++; colon != eol; colon++) {
+ if (*colon != ' ' && *colon != '\t')
+ break;
+ }
+ if (colon == eol)
+ value = "";
+ else
+ value = String(colon, eol - colon);
+
+ String oldValue = headerFields.get(lastKey);
+ if (!oldValue.isNull()) {
+ String tmp = oldValue;
+ tmp += ", ";
+ tmp += value;
+ value = tmp;
+ }
+
+ headerFields.set(lastKey, value);
+ }
+ }
+ }
+
+ return headerFields;
+}
+
+NPError PluginView::handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders)
+{
+ if (!url || !len || !buf)
+ return NPERR_INVALID_PARAM;
+
+ FrameLoadRequest frameLoadRequest;
+
+ HTTPHeaderMap headerFields;
+ Vector<char> buffer;
+
+ if (file) {
+ NPError readResult = handlePostReadFile(buffer, len, buf);
+ if(readResult != NPERR_NO_ERROR)
+ return readResult;
+ } else {
+ buffer.resize(len);
+ memcpy(buffer.data(), buf, len);
+ }
+
+ const char* postData = buffer.data();
+ int postDataLength = buffer.size();
+
+ if (allowHeaders) {
+ if (startsWithBlankLine(buffer)) {
+ postData++;
+ postDataLength--;
+ } else {
+ int location = locationAfterFirstBlankLine(buffer);
+ if (location != -1) {
+ // If the blank line is somewhere in the middle of the buffer, everything before is the header
+ headerFields = parseRFC822HeaderFields(buffer, location);
+ unsigned dataLength = buffer.size() - location;
+
+ // Sometimes plugins like to set Content-Length themselves when they post,
+ // but WebFoundation does not like that. So we will remove the header
+ // and instead truncate the data to the requested length.
+ String contentLength = headerFields.get("Content-Length");
+
+ if (!contentLength.isNull())
+ dataLength = min(contentLength.toInt(), (int)dataLength);
+ headerFields.remove("Content-Length");
+
+ postData += location;
+ postDataLength = dataLength;
+ }
+ }
+ }
+
+ frameLoadRequest.resourceRequest().setHTTPMethod("POST");
+ frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url));
+ frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields);
+ frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(postData, postDataLength));
+ frameLoadRequest.setFrameName(target);
+
+ return load(frameLoadRequest, sendNotification, notifyData);
+}
+
+#ifdef PLUGIN_SCHEDULE_TIMER
+uint32 PluginView::scheduleTimer(NPP instance, uint32 interval, bool repeat,
+ void (*timerFunc)(NPP, uint32 timerID))
+{
+ return m_timerList.schedule(instance, interval, repeat, timerFunc);
+}
+
+void PluginView::unscheduleTimer(NPP instance, uint32 timerID)
+{
+ m_timerList.unschedule(instance, timerID);
+}
+#endif
+
+void PluginView::invalidateWindowlessPluginRect(const IntRect& rect)
+{
+ if (!isVisible())
+ return;
+
+ RenderObject* renderer = m_element->renderer();
+ if (!renderer)
+ return;
+
+ IntRect dirtyRect = rect;
+ dirtyRect.move(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop());
+ renderer->repaintRectangle(dirtyRect);
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h
index 9256256..1a189e8 100644
--- a/WebCore/plugins/PluginView.h
+++ b/WebCore/plugins/PluginView.h
@@ -1,6 +1,7 @@
+
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,36 +28,37 @@
#ifndef PluginView_H
#define PluginView_H
-#ifdef ANDROID_PLUGINS
-
-#include "PluginViewAndroid.h"
-
-namespace WebCore {
- typedef PluginViewAndroid PluginView;
-}
-
-#else // !defined(ANDROID_PLUGINS)
-
-#include <winsock2.h>
-#include <windows.h>
-
#include "CString.h"
+#include "FrameLoadRequest.h"
#include "IntRect.h"
#include "KURL.h"
#include "PlatformString.h"
#include "PluginStream.h"
-#include "PluginQuirkSet.h"
#include "ResourceRequest.h"
#include "Timer.h"
#include "Widget.h"
-#include "npapi.h"
+#include "npruntime_internal.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
-namespace KJS {
+#ifdef PLUGIN_SCHEDULE_TIMER
+#include "PluginTimer.h"
+#endif
+
+#if PLATFORM(WIN_OS) && PLATFORM(QT)
+typedef struct HWND__* HWND;
+typedef HWND PlatformPluginWidget;
+#elif defined(ANDROID_PLUGINS)
+typedef struct PluginWidgetAndroid* PlatformPluginWidget;
+#else
+typedef PlatformWidget PlatformPluginWidget;
+#endif
+
+namespace JSC {
namespace Bindings {
class Instance;
}
@@ -65,11 +67,12 @@ namespace KJS {
namespace WebCore {
class Element;
class Frame;
- struct FrameLoadRequest;
class KeyboardEvent;
class MouseEvent;
class KURL;
+#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
class PluginMessageThrottlerWin;
+#endif
class PluginPackage;
class PluginRequest;
class PluginStream;
@@ -82,11 +85,28 @@ namespace WebCore {
PluginStatusLoadedSuccessfully
};
- class PluginView : public Widget, private PluginStreamClient {
- friend static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM);
+ class PluginRequest {
+ public:
+ PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups)
+ : m_frameLoadRequest(frameLoadRequest)
+ , m_notifyData(notifyData)
+ , m_sendNotification(sendNotification)
+ , m_shouldAllowPopups(shouldAllowPopups) { }
+ public:
+ const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; }
+ void* notifyData() const { return m_notifyData; }
+ bool sendNotification() const { return m_sendNotification; }
+ bool shouldAllowPopups() const { return m_shouldAllowPopups; }
+ private:
+ FrameLoadRequest m_frameLoadRequest;
+ void* m_notifyData;
+ bool m_sendNotification;
+ bool m_shouldAllowPopups;
+ };
+ class PluginView : public Widget, private PluginStreamClient {
public:
- PluginView(Frame* parentFrame, const IntSize&, PluginPackage* plugin, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
+ static PluginView* create(Frame* parentFrame, const IntSize&, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
virtual ~PluginView();
PluginPackage* plugin() const { return m_plugin.get(); }
@@ -95,7 +115,7 @@ namespace WebCore {
void setNPWindowRect(const IntRect&);
static PluginView* currentPluginView();
- KJS::Bindings::Instance* bindingInstance();
+ PassRefPtr<JSC::Bindings::Instance> bindingInstance();
PluginStatus status() const { return m_status; }
@@ -108,36 +128,59 @@ namespace WebCore {
int32 write(NPStream* stream, int32 len, void* buffer);
NPError destroyStream(NPStream* stream, NPReason reason);
const char* userAgent();
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ static const char* userAgentStatic();
+#endif
void status(const char* message);
NPError getValue(NPNVariable variable, void* value);
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ static NPError getValueStatic(NPNVariable variable, void* value);
+#endif
NPError setValue(NPPVariable variable, void* value);
void invalidateRect(NPRect*);
void invalidateRegion(NPRegion);
void forceRedraw();
void pushPopupsEnabledState(bool state);
void popPopupsEnabledState();
+#ifdef PLUGIN_SCHEDULE_TIMER
+ uint32 scheduleTimer(NPP, uint32 interval, bool repeat,
+ void (*timerFunc)(NPP, uint32 timerID));
+ void unscheduleTimer(NPP, uint32 timerID);
+#endif
+
+ virtual void invalidateRect(const IntRect&);
bool arePopupsAllowed() const;
+ void setJavaScriptPaused(bool);
+
void disconnectStream(PluginStream*);
void streamDidFinishLoading(PluginStream* stream) { disconnectStream(stream); }
// Widget functions
- virtual void setFrameGeometry(const IntRect&);
- virtual void geometryChanged() const;
+ virtual void setFrameRect(const IntRect&);
+ virtual void frameRectsChanged() const;
virtual void setFocus();
virtual void show();
virtual void hide();
virtual void paint(GraphicsContext*, const IntRect&);
- virtual IntRect windowClipRect() const;
+
+ // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore,
+ // e.g., in overflow:auto sections. The clip rects coordinates are in the containing window's coordinate space.
+ // This clip includes any clips that the widget itself sets up for its children.
+ IntRect windowClipRect() const;
+
virtual void handleEvent(Event*);
virtual void setParent(ScrollView*);
+ virtual void setParentVisible(bool);
- virtual void attachToWindow();
- virtual void detachFromWindow();
+ virtual bool isPluginView() const { return true; }
+#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
+ static LRESULT CALLBACK PluginViewWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
WNDPROC pluginWndProc() const { return m_pluginWndProc; }
+#endif
// Used for manual loading
void didReceiveResponse(const ResourceResponse&);
@@ -147,7 +190,14 @@ namespace WebCore {
static bool isCallingPlugin();
+#if PLATFORM(QT)
+ bool isNPAPIPlugin() const { return m_isNPAPIPlugin; }
+ void setIsNPAPIPlugin(bool b) { m_isNPAPIPlugin = b; }
+#endif
+
private:
+ PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
+
void setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues);
void init();
bool start();
@@ -155,10 +205,15 @@ namespace WebCore {
static void setCurrentPluginView(PluginView*);
NPError load(const FrameLoadRequest&, bool sendNotification, void* notifyData);
NPError handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders);
+ NPError handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf);
+ static void freeStringArray(char** stringArray, int length);
void setCallingPlugin(bool) const;
+
+ void invalidateWindowlessPluginRect(const IntRect&);
+
+ Frame* m_parentFrame;
RefPtr<PluginPackage> m_plugin;
Element* m_element;
- Frame* m_parentFrame;
bool m_isStarted;
KURL m_url;
KURL m_baseURL;
@@ -175,16 +230,24 @@ namespace WebCore {
void popPopupsStateTimerFired(Timer<PluginView>*);
Timer<PluginView> m_popPopupsStateTimer;
+#ifndef NP_NO_CARBON
bool dispatchNPEvent(NPEvent&);
- OwnPtr<PluginMessageThrottlerWin> m_messageThrottler;
-
- void updateWindow() const;
- void determineQuirks(const String& mimeType);
+#endif
+ void updatePluginWidget() const;
void paintMissingPluginIcon(GraphicsContext*, const IntRect&);
void handleKeyboardEvent(KeyboardEvent*);
void handleMouseEvent(MouseEvent*);
+#ifdef ANDROID_PLUGINS
+ // called at the end of the base constructor
+ void platformInit();
+#endif
+#ifdef PLUGIN_PLATFORM_SETVALUE
+ // called if the default setValue does not recognize the variable
+ NPError platformSetValue(NPPVariable variable, void* value);
+#endif
+
int m_mode;
int m_paramCount;
char** m_paramNames;
@@ -196,35 +259,62 @@ namespace WebCore {
NPP m_instance;
NPP_t m_instanceStruct;
NPWindow m_npWindow;
-
+
Vector<bool, 4> m_popupStateStack;
HashSet<RefPtr<PluginStream> > m_streams;
Vector<PluginRequest*> m_requests;
- PluginQuirkSet m_quirks;
bool m_isWindowed;
bool m_isTransparent;
- bool m_isVisible;
- bool m_attachedToWindow;
bool m_haveInitialized;
- WNDPROC m_pluginWndProc;
- HWND m_window; // for windowed plug-ins
- mutable IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
- mutable IntRect m_windowRect; // Our window rect.
+#if PLATFORM(QT)
+ bool m_isNPAPIPlugin;
+#endif
+#if PLATFORM(GTK) || defined(Q_WS_X11)
+ bool m_needsXEmbed;
+#endif
+
+#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
+ OwnPtr<PluginMessageThrottlerWin> m_messageThrottler;
+ WNDPROC m_pluginWndProc;
unsigned m_lastMessage;
bool m_isCallingPluginWndProc;
+#endif
+
+#ifdef PLUGIN_SCHEDULE_TIMER
+ PluginTimerList m_timerList;
+#endif
+
+#if PLATFORM(WIN_OS) && PLATFORM(QT)
+ // Only under Qt on Windows, the plugin widget (HWND) does not match the native widget (QWidget).
+ PlatformPluginWidget m_window; // for windowed plug-ins
+public:
+ PlatformPluginWidget platformPluginWidget() const { return m_window; }
+#elif defined(ANDROID_PLUGINS)
+public:
+ PlatformPluginWidget m_window;
+ PlatformPluginWidget platformPluginWidget() const { return m_window; } // MANUAL MERGE FIXME
+#else
+public:
+ PlatformPluginWidget platformPluginWidget() const { return platformWidget(); }
+#endif
+
+private:
+
+ mutable IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
+ mutable IntRect m_windowRect; // Our window rect.
bool m_loadManually;
RefPtr<PluginStream> m_manualStream;
+ bool m_isJavaScriptPaused;
+
static PluginView* s_currentPluginView;
};
} // namespace WebCore
-#endif // !defined(ANDROID_PLUGINS)
-
#endif
diff --git a/WebCore/plugins/android/PlugInInfoStoreAndroid.cpp b/WebCore/plugins/android/PlugInInfoStoreAndroid.cpp
deleted file mode 100644
index 780e5f0..0000000
--- a/WebCore/plugins/android/PlugInInfoStoreAndroid.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PluginInfoStore.h"
-#include "PluginDatabaseAndroid.h"
-#include "PluginPackageAndroid.h"
-
-namespace WebCore {
-
-PluginInfo* PluginInfoStore::createPluginInfoForPluginAtIndex(unsigned i)
-{
- PluginDatabaseAndroid *db = PluginDatabaseAndroid::installedPlugins();
- PluginInfo* info = new PluginInfo;
- PluginPackageAndroid* package = db->plugins()[i];
-
- info->name = package->name();
- info->file = package->fileName();
- info->desc = package->description();
-
- const MIMEToDescriptionsMap& mimeToDescriptions = package->mimeToDescriptions();
- MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end();
- for (MIMEToDescriptionsMap::const_iterator it = mimeToDescriptions.begin(); it != end; ++it) {
- MimeClassInfo* mime = new MimeClassInfo;
- info->mimes.append(mime);
-
- mime->type = it->first;
- mime->desc = it->second;
- mime->plugin = info;
-
- Vector<String> extensions = package->mimeToExtensions().get(mime->type);
-
- for (unsigned i = 0; i < extensions.size(); i++) {
- if (i > 0)
- mime->suffixes += ",";
-
- mime->suffixes += extensions[i];
- }
- }
-
- return info;
-}
-
-unsigned PluginInfoStore::pluginCount() const
-{
- return PluginDatabaseAndroid::installedPlugins()->plugins().size();
-}
-
-bool PluginInfoStore::supportsMIMEType(const WebCore::String& mimeType)
-{
- return PluginDatabaseAndroid::installedPlugins()->isMIMETypeRegistered(mimeType);
-}
-
-void refreshPlugins(bool reloadOpenPages)
-{
- PluginDatabaseAndroid::installedPlugins()->refresh();
-
- if (reloadOpenPages) {
- // FIXME: reload open pages
- }
-}
-
-}
diff --git a/WebCore/plugins/android/PluginDatabaseAndroid.cpp b/WebCore/plugins/android/PluginDatabaseAndroid.cpp
deleted file mode 100644
index 411855c..0000000
--- a/WebCore/plugins/android/PluginDatabaseAndroid.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-#ifdef ANDROID_PLUGINS
-
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PluginDatabaseAndroid.h"
-#include "PluginPackageAndroid.h"
-#include "PluginViewAndroid.h"
-#include "Frame.h"
-#include <sys/types.h>
-#include <dirent.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "PluginDebug.h"
-
-namespace WebCore {
-
-String PluginDatabaseAndroid::s_defaultPluginsPath;
-
-PluginDatabaseAndroid* PluginDatabaseAndroid::installedPlugins()
-{
- static PluginDatabaseAndroid* plugins = 0;
-
- if (!plugins) {
- plugins = new PluginDatabaseAndroid;
- plugins->refresh();
- }
-
- return plugins;
-}
-
-void PluginDatabaseAndroid::setDefaultPluginsPath(const String& path)
-{
- // Change the default plugins path and rescan.
- if(path != s_defaultPluginsPath) {
- s_defaultPluginsPath = path;
- installedPlugins()->refresh();
- }
-}
-
-PluginDatabaseAndroid::PluginDatabaseAndroid()
- : m_pluginsPaths()
- , m_plugins()
-{
-}
-
-PluginDatabaseAndroid::~PluginDatabaseAndroid()
-{
-}
-
-void PluginDatabaseAndroid::addExtraPluginPath(const String& path)
-{
- m_pluginsPaths.append(path);
- refresh();
-}
-
-bool PluginDatabaseAndroid::addPluginFile(const String& path)
-{
- PLUGIN_LOG("Adding plugin \"%s\"\n", path.utf8().data());
-
- // Check if the plugin is already loaded.
- PluginPackageAndroid* plugin = findPluginByPath(path);
-
- // Stat the file to check we can access it.
- struct stat statbuf;
- if(stat(path.utf8().data(), &statbuf)) {
- // Stat failed. We can't access this file.
- PLUGIN_LOG("Couldn't stat library \"%s\": %s\n",
- path.utf8().data(), strerror(errno));
- // Well, can't load this plugin, then.
- if(plugin) {
- // If we previous succeeded loading it, unload it now.
- removePlugin(plugin);
- }
- // Failed to load.
- return false;
- }
-
- // Check the modification time.
- uint32 lastModified = statbuf.st_mtime;
- if(plugin) {
- // Compare to the currently loaded version.
- if(lastModified == plugin->getLastModified()) {
- // It's the same plugin. No new actions required.
- return true;
- } else {
- // It has been modified. Unload the old version.
- removePlugin(plugin);
- }
- }
-
- // If we get here, we either just unloaded an old plugin, or this
- // is a new one. Create a new package.
- PluginPackageAndroid* package =
- PluginPackageAndroid::createPackage(path, lastModified);
- if(package) {
- // Success, add to the vector of plugins.
- PLUGIN_LOG("Successfully added plugin \"%s\"\n", path.utf8().data());
- m_plugins.append(package);
- return true;
- } else {
- // Failed.
- return false;
- }
-}
-
-bool PluginDatabaseAndroid::addPluginsInDirectory(const String& path)
-{
- // Open a directory iterator
- DIR* dir_it = opendir(path.utf8().data());
- if(!dir_it) {
- PLUGIN_LOG("Cannot open directory \"%s\"\n",
- path.utf8().data());
- return false;
- }
- // Scan the directory for "*.so" and "*.so.*" files.
- struct dirent* entry;
- while((entry = readdir(dir_it)) != NULL) {
- const char* name = entry->d_name;
- // Skip current and parent directory entries.
- if(!strcmp(name, ".") || !strcmp(name, ".."))
- continue;
- const char* so = strstr(name, ".so");
- if(so && (so[3] == 0 || so[3] == '.')) {
- // Matches our pattern, add it.
- addPluginFile(path + "/" + name);
- }
- }
- closedir(dir_it);
- return true;
-}
-
-void PluginDatabaseAndroid::removePlugin(PluginPackageAndroid* plugin)
-{
- // Find this plugin in the array and remove it.
- for(unsigned i = 0; i < m_plugins.size(); ++i) {
- if(m_plugins[i] == plugin) {
- PLUGIN_LOG("Removed plugin \"%s\"\n",
- plugin->path().utf8().data());
- // This will cause a reference count to decrement. When
- // the plugin actually stops getting used by all
- // documents, its instance will delete itself.
- m_plugins.remove(i);
- break;
- }
- }
- PLUGIN_LOG("Tried to remove plugin %p which didn't exist!\n", plugin);
-}
-
-bool PluginDatabaseAndroid::refresh()
-{
- PLUGIN_LOG("PluginDatabaseAndroid::refresh()\n");
-
- // Don't delete existing plugins. The directory scan will add new
- // plugins and also refresh old plugins if their file is modified
- // since the last check.
-
- // Scan each directory and add any plugins found in them. This is
- // not recursive.
- if(s_defaultPluginsPath.length() > 0)
- addPluginsInDirectory(s_defaultPluginsPath);
- for(unsigned i = 0; i < m_pluginsPaths.size(); ++i)
- addPluginsInDirectory(m_pluginsPaths[i]);
-
- // Now stat() all plugins and remove any that we can't
- // access. This handles the case of a plugin being deleted at
- // runtime.
- for(unsigned i = 0; i < m_plugins.size();) {
- struct stat statbuf;
- if(stat(m_plugins[i]->path().utf8().data(), &statbuf)) {
- // It's gone away. Remove it from the list.
- m_plugins.remove(i);
- } else {
- ++i;
- }
- }
-
- return true;
-}
-
-Vector<PluginPackageAndroid*> PluginDatabaseAndroid::plugins() const
-{
- Vector<PluginPackageAndroid*> result;
-
- for(PackageRefVector::const_iterator it = m_plugins.begin();
- it != m_plugins.end(); ++it)
- result.append(it->get());
-
- return result;
-}
-
-bool PluginDatabaseAndroid::isMIMETypeRegistered(const String& mimeType) const
-{
- // Iterate through every package
- for(PackageRefVector::const_iterator it = m_plugins.begin();
- it != m_plugins.end(); ++it) {
- // Check if this package has the MIME type mapped to an extension
- const PluginPackageAndroid *package = it->get();
- const MIMEToExtensionsMap& mime_extension_map =
- package->mimeToExtensions();
- if(mime_extension_map.find(mimeType) != mime_extension_map.end()) {
- // Found it
- return true;
- }
- }
- // No package has this MIME type
- return false;
-}
-
-bool PluginDatabaseAndroid::isPluginBlacklisted(PluginPackageAndroid* plugin)
-{
- // If there is ever a plugin in the wild which causes the latest
- // version of Android to crash, then stick a check here for it and
- // return true when matched.
- return false;
-}
-
-PluginPackageAndroid* PluginDatabaseAndroid::pluginForMIMEType(
- const String& mimeType)
-{
- // Todo: these data structures are not right. This is inefficient.
- // Iterate through every package
- for(PackageRefVector::iterator it = m_plugins.begin();
- it != m_plugins.end(); ++it) {
- // Check if this package has the MIME type mapped to a description
- PluginPackageAndroid *package = it->get();
- const MIMEToDescriptionsMap& mime_desc_map =
- package->mimeToDescriptions();
- if(mime_desc_map.find(mimeType) != mime_desc_map.end()) {
- // Found it
- return package;
- }
- }
- // No package has this MIME type
- return NULL;
-}
-
-String PluginDatabaseAndroid::MIMETypeForExtension(const String& extension)
- const
-{
- // Todo: these data structures are not right. This is inefficient.
- // Iterate through every package
- for(PackageRefVector::const_iterator it = m_plugins.begin();
- it != m_plugins.end(); ++it) {
- // Check if this package has the MIME type mapped to an extension
- PluginPackageAndroid *package = it->get();
- const MIMEToDescriptionsMap& mime_desc_map =
- package->mimeToDescriptions();
- for(MIMEToDescriptionsMap::const_iterator map_it =
- mime_desc_map.begin();
- map_it != mime_desc_map.end(); ++map_it) {
- if(map_it->second == extension) {
- // Found it
- return map_it->first;
- }
- }
- }
- // No MIME type matches this extension
- return String("");
-}
-
-PluginPackageAndroid* PluginDatabaseAndroid::findPlugin(const KURL& url,
- String& mimeType)
-{
- PluginPackageAndroid* plugin = pluginForMIMEType(mimeType);
- String filename = url.string();
-
- if (!plugin) {
- String filename = url.lastPathComponent();
- if (!filename.endsWith("/")) {
- int extensionPos = filename.reverseFind('.');
- if (extensionPos != -1) {
- String extension = filename.substring(extensionPos + 1);
-
- mimeType = MIMETypeForExtension(extension);
- if (mimeType.length()) {
- plugin = pluginForMIMEType(mimeType);
- }
- }
- }
- }
- // No MIME type matches this url
- return plugin;
-}
-
-PluginPackageAndroid* PluginDatabaseAndroid::findPluginByPath(
- const String& path)
-{
- for(PackageRefVector::iterator it = m_plugins.begin();
- it != m_plugins.end(); ++it) {
- if((*it)->path() == path)
- return it->get(); // Found it
- }
- return 0; // Not found.
-}
-
-PluginViewAndroid* PluginDatabaseAndroid::createPluginView(
- Frame* parentFrame,
- const IntSize& size,
- Element* element,
- const KURL& url,
- const Vector<String>& paramNames,
- const Vector<String>& paramValues,
- const String& mimeType,
- bool loadManually)
-{
- // if we fail to find a plugin for this MIME type, findPlugin will search for
- // a plugin by the file extension and update the MIME type, so pass a mutable String
- String mimeTypeCopy = mimeType;
- PluginPackageAndroid* plugin = findPlugin(url, mimeTypeCopy);
-
- // No plugin was found, try refreshing the database and searching again
- if (!plugin && refresh()) {
- mimeTypeCopy = mimeType;
- plugin = findPlugin(url, mimeTypeCopy);
- }
-
- return new PluginViewAndroid(parentFrame, size, plugin, element, url, paramNames, paramValues, mimeTypeCopy, loadManually);
-}
-
-}
-
-#endif
diff --git a/WebCore/plugins/android/PluginDatabaseAndroid.h b/WebCore/plugins/android/PluginDatabaseAndroid.h
deleted file mode 100644
index 72814e9..0000000
--- a/WebCore/plugins/android/PluginDatabaseAndroid.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifdef ANDROID_PLUGINS
-
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PluginDatabaseAndroid_H
-#define PluginDatabaseAndroid_H
-
-#include <wtf/Vector.h>
-
-#include "PlatformString.h"
-#include "PluginPackageAndroid.h"
-
-namespace WebCore {
- class Element;
- class Frame;
- class IntSize;
- class KURL;
- class PluginPackageAndroid;
- class PluginViewAndroid;
-
- class PluginDatabaseAndroid {
- public:
- ~PluginDatabaseAndroid();
-
- static PluginDatabaseAndroid* installedPlugins();
- PluginViewAndroid* createPluginView(Frame* parentFrame,
- const IntSize&,
- Element* element,
- const KURL& url,
- const Vector<String>& paramNames,
- const Vector<String>& paramValues,
- const String& mimeType,
- bool loadManually);
-
- bool refresh();
- Vector<PluginPackageAndroid*> plugins() const;
- bool isMIMETypeRegistered(const String& mimeType) const;
- void addExtraPluginPath(const String&);
- static bool isPluginBlacklisted(PluginPackageAndroid* plugin);
- static void setDefaultPluginsPath(const String&);
-
- private:
- explicit PluginDatabaseAndroid();
-
- bool addPluginFile(const String& path);
- bool addPluginsInDirectory(const String& path);
- PluginPackageAndroid* findPlugin(const KURL& url, String& mimeType);
- PluginPackageAndroid* pluginForMIMEType(const String& mimeType);
- String MIMETypeForExtension(const String& extension) const;
- PluginPackageAndroid* findPluginByPath(const String& path);
- void removePlugin(PluginPackageAndroid* plugin);
-
- // List of all paths to search for plugins
- Vector<String> m_pluginsPaths;
-
- // List of all PluginPackageAndroid instances
- typedef Vector<RefPtr<PluginPackageAndroid> > PackageRefVector;
- PackageRefVector m_plugins;
-
- // The default plugins path from Settings.
- static String s_defaultPluginsPath;
- };
-
-} // namespace WebCore
-
-#endif
-
-#endif
diff --git a/WebCore/plugins/android/PluginDebug.h b/WebCore/plugins/android/PluginDebug.h
deleted file mode 100644
index 8adbbd7..0000000
--- a/WebCore/plugins/android/PluginDebug.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifdef ANDROID_PLUGINS
-
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef PLUGIN_DEBUG_H__
-#define PLUGIN_DEBUG_H__
-
-// Include this file last to avoid clashes with the definition of LOG.
-
-#undef LOG
-#define LOG_TAG "WebKit"
-#include "utils/Log.h"
-
-// Define PLUGIN_DEBUG_LOCAL in an individual C++ file to enable for
-// that file only.
-
-// Define PLUGIN_DEBUG_GLOBAL to 1 to turn plug-in debug for all
-// Android plug-in code in this direectory.
-#define PLUGIN_DEBUG_GLOBAL 0
-
-#if PLUGIN_DEBUG_GLOBAL || defined(PLUGIN_DEBUG_LOCAL)
-# define PLUGIN_LOG(A, B...) do { LOGI( A , ## B ); } while(0)
-#else
-# define PLUGIN_LOG(A, B...) do { } while(0)
-#endif
-
-#endif // defined(PLUGIN_DEBUG_H__)
-
-#endif // defined(ANDROID_PLUGINS)
diff --git a/WebCore/plugins/android/PluginPackageAndroid.cpp b/WebCore/plugins/android/PluginPackageAndroid.cpp
deleted file mode 100644
index b8dca9a..0000000
--- a/WebCore/plugins/android/PluginPackageAndroid.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-#ifdef ANDROID_PLUGINS
-
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "WebCoreJni.h"
-#include "PluginPackageAndroid.h"
-#include "PluginDatabaseAndroid.h"
-
-#include "Timer.h"
-#include "DeprecatedString.h"
-#include "PlatformString.h"
-#include "CString.h"
-#include "npruntime_impl.h"
-
-#include <dlfcn.h>
-#include <errno.h>
-
-#include "PluginDebug.h"
-
-namespace WebCore {
-
-PluginPackageAndroid::PluginPackageAndroid(const String& path,
- uint32 lastModified)
- : m_path(path),
- m_name(),
- m_fileName(),
- m_description(),
- m_lastModified(lastModified),
- m_pluginFuncs(),
- m_mimeToDescriptions(),
- m_mimeToExtensions(),
- m_env(0),
- m_pluginObject(0),
- m_libraryHandle(NULL),
- m_libraryInitialized(false),
- m_NP_Initialize((NP_InitializeFuncPtr) NULL),
- m_NP_Shutdown((NP_ShutdownFuncPtr) NULL),
- m_NP_GetMIMEDescription((NP_GetMIMEDescriptionFuncPtr) NULL),
- m_NP_GetValue((NP_GetValueFuncPtr) NULL)
-{
- PLUGIN_LOG("Constructing PluginPackageAndroid\n");
- if(android::WebCoreJni::getJavaVM()->GetEnv((void**) &m_env,
- JNI_VERSION_1_4) != JNI_OK) {
- PLUGIN_LOG("GetEnv failed!");
- }
-}
-
-PluginPackageAndroid::~PluginPackageAndroid()
-{
- PLUGIN_LOG("Destructing PluginPackageAndroid\n");
- unload();
-}
-
-void PluginPackageAndroid::initializeBrowserFuncs()
-{
- // Initialize the NPN function pointers that we hand over to the
- // plugin.
-
- memset(&m_browserFuncs, 0, sizeof(m_browserFuncs));
-
- m_browserFuncs.size = sizeof(m_browserFuncs);
- m_browserFuncs.version = NP_VERSION_MINOR;
- m_browserFuncs.geturl = NPN_GetURL;
- m_browserFuncs.posturl = NPN_PostURL;
- m_browserFuncs.requestread = NPN_RequestRead;
- m_browserFuncs.newstream = NPN_NewStream;
- m_browserFuncs.write = NPN_Write;
- m_browserFuncs.destroystream = NPN_DestroyStream;
- m_browserFuncs.status = NPN_Status;
- m_browserFuncs.uagent = NPN_UserAgent;
- m_browserFuncs.memalloc = NPN_MemAlloc;
- m_browserFuncs.memfree = NPN_MemFree;
- m_browserFuncs.memflush = NPN_MemFlush;
- m_browserFuncs.reloadplugins = NPN_ReloadPlugins;
- m_browserFuncs.geturlnotify = NPN_GetURLNotify;
- m_browserFuncs.posturlnotify = NPN_PostURLNotify;
- m_browserFuncs.getvalue = NPN_GetValue;
- m_browserFuncs.setvalue = NPN_SetValue;
- m_browserFuncs.invalidaterect = NPN_InvalidateRect;
- m_browserFuncs.invalidateregion = NPN_InvalidateRegion;
- m_browserFuncs.forceredraw = NPN_ForceRedraw;
- m_browserFuncs.getJavaEnv = NPN_GetJavaEnv;
- m_browserFuncs.getJavaPeer = NPN_GetJavaPeer;
- m_browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState;
- m_browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState;
- m_browserFuncs.pluginthreadasynccall = NPN_PluginThreadAsyncCall;
-
- m_browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
- m_browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
- m_browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers;
- m_browserFuncs.getintidentifier = _NPN_GetIntIdentifier;
- m_browserFuncs.identifierisstring = _NPN_IdentifierIsString;
- m_browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier;
- m_browserFuncs.intfromidentifier = _NPN_IntFromIdentifier;
- m_browserFuncs.createobject = _NPN_CreateObject;
- m_browserFuncs.retainobject = _NPN_RetainObject;
- m_browserFuncs.releaseobject = _NPN_ReleaseObject;
- m_browserFuncs.invoke = _NPN_Invoke;
- m_browserFuncs.invokeDefault = _NPN_InvokeDefault;
- m_browserFuncs.evaluate = _NPN_Evaluate;
- m_browserFuncs.getproperty = _NPN_GetProperty;
- m_browserFuncs.setproperty = _NPN_SetProperty;
- m_browserFuncs.removeproperty = _NPN_RemoveProperty;
- m_browserFuncs.hasproperty = _NPN_HasProperty;
- m_browserFuncs.hasmethod = _NPN_HasMethod;
- m_browserFuncs.setexception = _NPN_SetException;
- m_browserFuncs.enumerate = _NPN_Enumerate;
-}
-
-jobject PluginPackageAndroid::createPluginObject(const char *name,
- const char *path,
- const char *fileName,
- const char *description)
-{
- // Create a Java "class Plugin" object instance
- jclass pluginClass = m_env->FindClass("android/webkit/Plugin");
- if(!pluginClass) {
- PLUGIN_LOG("Couldn't find class android.webkit.Plugin\n");
- return 0;
- }
- // Get Plugin(String, String, String, String, Context)
- jmethodID pluginConstructor = m_env->GetMethodID(
- pluginClass,
- "<init>",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
- if(!pluginConstructor) {
- PLUGIN_LOG("Couldn't get android.webkit.Plugin constructor\n");
- return 0;
- }
- // Make Java strings of name, path, fileName, description
- jstring javaName = m_env->NewStringUTF(name);
- jstring javaPath = m_env->NewStringUTF(m_path.utf8().data());
- jstring javaFileName = m_env->NewStringUTF(m_fileName.utf8().data());
- jstring javaDescription = m_env->NewStringUTF(description);
- // Make a plugin instance
- jobject pluginObject = m_env->NewObject(pluginClass,
- pluginConstructor,
- javaName,
- javaPath,
- javaFileName,
- javaDescription);
- return pluginObject;
-}
-
-jobject PluginPackageAndroid::getPluginListObject()
-{
- // Get WebView.getPluginList()
- jclass webViewClass = m_env->FindClass("android/webkit/WebView");
- if(!webViewClass) {
- PLUGIN_LOG("Couldn't find class android.webkit.WebView\n");
- return 0;
- }
- jmethodID getPluginList = m_env->GetStaticMethodID(
- webViewClass,
- "getPluginList",
- "()Landroid/webkit/PluginList;");
- if(!getPluginList) {
- PLUGIN_LOG("Couldn't find android.webkit.WebView.getPluginList()\n");
- return 0;
- }
- // Get the PluginList instance
- jobject pluginListObject = m_env->CallStaticObjectMethod(webViewClass,
- getPluginList);
- if(!pluginListObject) {
- PLUGIN_LOG("Couldn't get PluginList object\n");
- return 0;
- }
- return pluginListObject;
-}
-
-bool PluginPackageAndroid::addPluginObjectToList(jobject pluginList,
- jobject plugin)
-{
- // Add the Plugin object
- jclass pluginListClass = m_env->FindClass("android/webkit/PluginList");
- if(!pluginListClass) {
- PLUGIN_LOG("Couldn't find class android.webkit.PluginList\n");
- return false;
- }
- jmethodID addPlugin = m_env->GetMethodID(
- pluginListClass,
- "addPlugin",
- "(Landroid/webkit/Plugin;)V");
- if(!addPlugin) {
- PLUGIN_LOG("Couldn't find android.webkit.PluginList.addPlugin()\n");
- return false;
- }
- m_env->CallVoidMethod(pluginList,
- addPlugin,
- plugin);
- return true;
-}
-
-void PluginPackageAndroid::removePluginObjectFromList(jobject pluginList,
- jobject plugin)
-{
- // Remove the Plugin object
- jclass pluginListClass = m_env->FindClass("android/webkit/PluginList");
- if(!pluginListClass) {
- PLUGIN_LOG("Couldn't find class android.webkit.PluginList\n");
- return;
- }
- jmethodID removePlugin = m_env->GetMethodID(
- pluginListClass,
- "removePlugin",
- "(Landroid/webkit/Plugin;)V");
- if(!removePlugin) {
- PLUGIN_LOG("Couldn't find android.webkit.PluginList.removePlugin()\n");
- return;
- }
- m_env->CallVoidMethod(pluginList,
- removePlugin,
- plugin);
-}
-
-bool PluginPackageAndroid::load()
-{
- if(m_libraryHandle) {
- PLUGIN_LOG("Plugin \"%s\" already loaded\n", m_path.utf8().data());
- return true;
- }
-
- PLUGIN_LOG("Loading \"%s\"\n", m_path.utf8().data());
-
- // Open the library
- void *handle = dlopen(m_path.utf8().data(), RTLD_NOW);
- if(!handle) {
- PLUGIN_LOG("Couldn't load plugin library \"%s\": %s\n",
- m_path.utf8().data(), dlerror());
- return false;
- }
- m_libraryHandle = handle;
- // This object will call dlclose() and set m_libraryHandle to NULL
- // when going out of scope.
- DynamicLibraryCloser dlCloser(this);
-
- // Get the four entry points we need for Linux Netscape Plug-ins
- if(!getEntryPoint("NP_Initialize", (void **) &m_NP_Initialize) ||
- !getEntryPoint("NP_Shutdown", (void **) &m_NP_Shutdown) ||
- !getEntryPoint("NP_GetMIMEDescription",
- (void **) &m_NP_GetMIMEDescription) ||
- !getEntryPoint("NP_GetValue", (void **) &m_NP_GetValue)) {
- // If any of those failed to resolve, fail the entire load
- return false;
- }
-
- // Get the plugin name and description using NP_GetValue
- const char *name;
- const char *description;
- if(m_NP_GetValue(NULL, NPPVpluginNameString,
- &name) != NPERR_NO_ERROR ||
- m_NP_GetValue(NULL, NPPVpluginDescriptionString,
- &description) != NPERR_NO_ERROR) {
- PLUGIN_LOG("Couldn't get name/description using NP_GetValue\n");
- return false;
- }
-
- PLUGIN_LOG("Plugin name: \"%s\"\n", name);
- PLUGIN_LOG("Plugin description: \"%s\"\n", description);
- m_name = name;
- m_description = description;
-
- // fileName is just the trailing part of the path
- int last_slash = m_path.reverseFind('/');
- if(last_slash < 0)
- m_fileName = m_path;
- else
- m_fileName = m_path.substring(last_slash + 1);
-
- // Grab the MIME description. This is in the format, e.g:
- // application/x-somescriptformat:ssf:Some Script Format
- const char *mime_description = m_NP_GetMIMEDescription();
- if(!initializeMIMEDescription(mime_description)) {
- PLUGIN_LOG("Bad MIME description: \"%s\"\n",
- mime_description);
- return false;
- }
-
- // Create a new Java Plugin object.
- jobject pluginObject = createPluginObject(name,
- m_path.utf8().data(),
- m_fileName.utf8().data(),
- description);
- if(!pluginObject) {
- PLUGIN_LOG("Couldn't create Java Plugin\n");
- return false;
- }
-
- // Provide the plugin with our browser function table and grab its
- // plugin table. Provide the Java environment and the Plugin which
- // can be used to override the defaults if the plugin wants.
- initializeBrowserFuncs();
- memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
- m_pluginFuncs.size = sizeof(m_pluginFuncs);
- if(m_NP_Initialize(&m_browserFuncs,
- &m_pluginFuncs,
- m_env,
- pluginObject) != NPERR_NO_ERROR) {
- PLUGIN_LOG("Couldn't initialize plugin\n");
- return false;
- }
-
- // Add the Plugin to the PluginList
- jobject pluginListObject = getPluginListObject();
- if(!pluginListObject) {
- PLUGIN_LOG("Couldn't get PluginList object\n");
- m_NP_Shutdown();
- return false;
- }
- if(!addPluginObjectToList(pluginListObject, pluginObject)) {
- PLUGIN_LOG("Couldn't add Plugin to PluginList\n");
- m_NP_Shutdown();
- return false;
- }
-
- // Retain the Java Plugin object
- m_pluginObject = m_env->NewGlobalRef(pluginObject);
-
- // Need to call NP_Shutdown at some point in the future.
- m_libraryInitialized = true;
-
- // Don't close the library - loaded OK.
- dlCloser.ok();
- // Retain the handle so we can close it in the future.
- m_libraryHandle = handle;
-
- PLUGIN_LOG("Loaded OK\n");
- return true;
-}
-
-void PluginPackageAndroid::unload()
-{
- if(!m_libraryHandle) {
- PLUGIN_LOG("Plugin \"%s\" already unloaded\n", m_path.utf8().data());
- return; // No library loaded
- }
- PLUGIN_LOG("Unloading \"%s\"\n", m_path.utf8().data());
-
- if(m_libraryInitialized) {
- // Shutdown the plug-in
- ASSERT(m_NP_Shutdown != NULL);
- PLUGIN_LOG("Calling NP_Shutdown\n");
- NPError err = m_NP_Shutdown();
- if(err != NPERR_NO_ERROR)
- PLUGIN_LOG("Couldn't shutdown plug-in \"%s\"\n",
- m_path.utf8().data());
- m_libraryInitialized = false;
-
- // Remove the plugin from the PluginList
- if(m_pluginObject) {
- jobject pluginListObject = getPluginListObject();
- if(pluginListObject) {
- removePluginObjectFromList(pluginListObject, m_pluginObject);
- }
- // Remove a reference to the Plugin object so it can
- // garbage collect.
- m_env->DeleteGlobalRef(m_pluginObject);
- m_pluginObject = 0;
- }
- }
-
- PLUGIN_LOG("Closing library\n");
- dlclose(m_libraryHandle);
- m_libraryHandle = 0;
- memset(&m_browserFuncs, 0, sizeof(m_browserFuncs));
- memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
- m_NP_Initialize = 0;
- m_NP_Shutdown = 0;
- m_NP_GetMIMEDescription = 0;
- m_NP_GetValue = 0;
-}
-
-const NPPluginFuncs* PluginPackageAndroid::pluginFuncs() const
-{
- ASSERT(m_libraryHandle && m_libraryInitialized);
- return &m_pluginFuncs;
-}
-
-PluginPackageAndroid* PluginPackageAndroid::createPackage(const String& path,
- uint32 lastModified)
-{
- PluginPackageAndroid* package = new PluginPackageAndroid(path,
- lastModified);
-
- if (!package->load()) {
- delete package;
- return 0;
- }
-
- return package;
-}
-
-bool PluginPackageAndroid::getEntryPoint(const char *name, void **entry_point)
-{
- dlerror();
- *entry_point = dlsym(m_libraryHandle, name);
- const char *error = dlerror();
- if(error == NULL && *entry_point != NULL) {
- return true;
- } else {
- PLUGIN_LOG("Couldn't get entry point \"%s\": %s\n",
- name, error);
- return false;
- }
-}
-
-bool PluginPackageAndroid::initializeMIMEEntry(const String& mimeEntry)
-{
- // Each part is split into 3 fields separated by colons
- // Field 1 is the MIME type (e.g "application/x-shockwave-flash").
- // Field 2 is a comma separated list of file extensions.
- // Field 3 is a human readable short description.
- Vector<String> fields = mimeEntry.split(':', true);
- if(fields.size() != 3)
- return false;
-
- const String& mimeType = fields[0];
- Vector<String> extensions = fields[1].split(',', true);
- const String& description = fields[2];
-
- PLUGIN_LOG("mime_type: \"%s\"\n",
- mimeType.utf8().data());
- PLUGIN_LOG("extensions: \"%s\"\n",
- fields[1].utf8().data());
- PLUGIN_LOG("description: \"%s\"\n",
- description.utf8().data());
-
- // Map the mime type to the vector of extensions and the description
- if(!extensions.isEmpty())
- m_mimeToExtensions.set(mimeType, extensions);
- if(!description.isEmpty())
- m_mimeToDescriptions.set(mimeType, description);
-
- return true;
-}
-
-bool PluginPackageAndroid::initializeMIMEDescription(
- const String& mimeDescription)
-{
- PLUGIN_LOG("MIME description: \"%s\"\n", mimeDescription.utf8().data());
-
- // Clear out the current mappings.
- m_mimeToDescriptions.clear();
- m_mimeToExtensions.clear();
-
- // Split the description into its component entries, separated by
- // semicolons.
- Vector<String> mimeEntries = mimeDescription.split(';', true);
-
- // Iterate through the entries, adding them to the MIME mappings.
- for(Vector<String>::const_iterator it = mimeEntries.begin();
- it != mimeEntries.end(); ++it) {
- if(!initializeMIMEEntry(*it)) {
- PLUGIN_LOG("Bad MIME entry: \"%s\"\n", it->utf8().data());
- m_mimeToDescriptions.clear();
- m_mimeToExtensions.clear();
- return false;
- }
- }
-
- return true;
-}
-
-PluginPackageAndroid::DynamicLibraryCloser::~DynamicLibraryCloser()
-{
- // Close the PluginPackageAndroid's library
- if(m_package)
- {
- if(m_package->m_libraryHandle)
- {
- dlclose(m_package->m_libraryHandle);
- m_package->m_libraryHandle = NULL;
- }
- m_package = NULL;
- }
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/WebCore/plugins/android/PluginPackageAndroid.h b/WebCore/plugins/android/PluginPackageAndroid.h
deleted file mode 100644
index d78df1e..0000000
--- a/WebCore/plugins/android/PluginPackageAndroid.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifdef ANDROID_PLUGINS
-
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PluginPackageAndroid_H
-#define PluginPackageAndroid_H
-
-#include "PlatformString.h"
-#include "StringHash.h"
-#include "Timer.h"
-#include "npfunctions.h"
-#include <wtf/HashMap.h>
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
- typedef HashMap<String, String> MIMEToDescriptionsMap;
- typedef HashMap<String, Vector<String> > MIMEToExtensionsMap;
-
- class PluginPackageAndroid : public RefCounted<PluginPackageAndroid> {
- public:
- ~PluginPackageAndroid();
- static PluginPackageAndroid* createPackage(const String& path,
- uint32 lastModified);
-
- String path() const { return m_path; }
- String name() const { return m_name; }
- String fileName() const { return m_fileName; }
- String description() const { return m_description; }
- uint32 getLastModified() const { return m_lastModified; }
-
- const MIMEToDescriptionsMap& mimeToDescriptions() const {
- return m_mimeToDescriptions;
- }
- const MIMEToExtensionsMap& mimeToExtensions() const {
- return m_mimeToExtensions;
- }
-
- bool load();
- void unload();
-
- const NPPluginFuncs* pluginFuncs() const;
-
- private:
- // Simple class which calls dlclose() on a dynamic library when going
- // out of scope. Call ok() if the handle should stay open.
- class DynamicLibraryCloser
- {
- public:
- DynamicLibraryCloser(PluginPackageAndroid *package)
- : m_package(package) { }
- ~DynamicLibraryCloser();
- void ok() { m_package = NULL; }
- private:
- PluginPackageAndroid *m_package;
- };
- friend class DynamicLibraryCloser;
-
- PluginPackageAndroid(const String& path,
- uint32 lastModified);
-
- // Set all the NPN function pointers in m_browserFuncs
- void initializeBrowserFuncs();
-
- // Call dlsym() and set *entry_point to the return value for
- // the symbol 'name'. Return true if the symbol exists.
- bool getEntryPoint(const char *name, void **entry_point);
-
- // Initialize m_mimeToDescriptions and m_mimeToExtensions from
- // this individual MIME entry. If badly formatted, returns
- // false.
- bool initializeMIMEEntry(const String& mime_entry);
-
- // Splits the MIME description into its entries and passes
- // them to initializeMIMEEntry. Returns false if any of the
- // description is badly format.
- bool initializeMIMEDescription(const String& mime_description);
-
- // Create a Java Plugin object instance
- jobject createPluginObject(const char *name,
- const char *path,
- const char *fileName,
- const char *description);
-
- // Get hold of the Java PluginList instance.
- jobject getPluginListObject();
-
- // Add the plugin to the PluginList.
- bool addPluginObjectToList(jobject pluginList,
- jobject plugin);
-
- // Remove the plugin from the Pluginlist
- void removePluginObjectFromList(jobject pluginList,
- jobject plugin);
-
- String m_path; // Path to open this library
- String m_name; // Human readable name e.g "Shockwave Flash"
- String m_fileName; // Name of the file e.g "libflashplayer.so"
- String m_description; // Verbose string e.g "Shockwave Flash 9.0 r48"
- uint32 m_lastModified; // Last modification time, Unix seconds.
-
- NPNetscapeFuncs m_browserFuncs;
- NPPluginFuncs m_pluginFuncs;
- MIMEToDescriptionsMap m_mimeToDescriptions;
- MIMEToExtensionsMap m_mimeToExtensions;
-
- // The Java environment.
- JNIEnv *m_env;
-
- // The Java Plugin object.
- jobject m_pluginObject;
-
- // Handle to the dynamic library. Non-NULL if open.
- void *m_libraryHandle;
-
- // True if the library is in the initialized state
- // (NP_Initialize called)
- bool m_libraryInitialized;
-
- // Entry points into the library obtained using dlsym()
- NP_InitializeFuncPtr m_NP_Initialize;
- NP_ShutdownFuncPtr m_NP_Shutdown;
- NP_GetMIMEDescriptionFuncPtr m_NP_GetMIMEDescription;
- NP_GetValueFuncPtr m_NP_GetValue;
- };
-} // namespace WebCore
-
-#endif
-
-#endif
diff --git a/WebCore/plugins/android/PluginViewAndroid.cpp b/WebCore/plugins/android/PluginViewAndroid.cpp
deleted file mode 100644
index 87dbe11..0000000
--- a/WebCore/plugins/android/PluginViewAndroid.cpp
+++ /dev/null
@@ -1,567 +0,0 @@
-#ifdef ANDROID_PLUGINS
-
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PluginViewAndroid.h"
-
-#include "Document.h"
-#include "Element.h"
-#include "FrameLoader.h"
-#include "FrameLoadRequest.h"
-#include "FrameTree.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "HTMLNames.h"
-#include "HTMLPlugInElement.h"
-#include "Image.h"
-#include "MIMETypeRegistry.h"
-#include "NotImplemented.h"
-#include "Page.h"
-#include "PlatformGraphicsContext.h"
-#include "PluginPackageAndroid.h"
-#include "kjs_binding.h"
-#include "kjs_proxy.h"
-#include "kjs_window.h"
-#include "android_graphics.h"
-#include "SkCanvas.h"
-#include "npruntime_impl.h"
-#include "runtime_root.h"
-#include "Settings.h"
-#include <kjs/JSLock.h>
-#include <kjs/value.h>
-#include <wtf/ASCIICType.h>
-#include "runtime.h"
-#include "WebViewCore.h"
-
-#include "PluginDebug.h"
-
-using KJS::ExecState;
-using KJS::Interpreter;
-using KJS::JSLock;
-using KJS::JSObject;
-using KJS::JSValue;
-using KJS::UString;
-
-using std::min;
-
-using namespace WTF;
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-PluginViewAndroid* PluginViewAndroid::s_currentPluginView = 0;
-
-void PluginViewAndroid::setParent(ScrollView* parent)
-{
- if (parent)
- init();
-}
-
-bool PluginViewAndroid::start()
-{
- if (m_isStarted)
- return false;
-
- ASSERT(m_plugin);
- ASSERT(m_plugin->pluginFuncs()->newp);
-
- NPError npErr;
- PluginViewAndroid::setCurrentPluginView(this);
- {
- KJS::JSLock::DropAllLocks dropAllLocks;
- npErr = m_plugin->pluginFuncs()->newp((NPMIMEType)m_mimeType.data(),
- m_instance,
- m_mode,
- m_paramCount,
- m_paramNames,
- m_paramValues,
- NULL);
- if(npErr)
- PLUGIN_LOG("plugin->newp returned %d\n", static_cast<int>(npErr));
- }
- PluginViewAndroid::setCurrentPluginView(0);
-
- if (npErr != NPERR_NO_ERROR)
- return false;
-
- m_isStarted = true;
-
- return true;
-}
-
-void PluginViewAndroid::stop()
-{
- if (!m_isStarted)
- return;
-
- m_isStarted = false;
-
- KJS::JSLock::DropAllLocks dropAllLocks;
-
- // Destroy the plugin
- NPError npErr = m_plugin->pluginFuncs()->destroy(m_instance, 0);
- if(npErr)
- PLUGIN_LOG("Plugin destroy returned %d\n", static_cast<int>(npErr));
-
- m_instance->pdata = 0;
-}
-
-void PluginViewAndroid::setCurrentPluginView(PluginViewAndroid* pluginView)
-{
- s_currentPluginView = pluginView;
-}
-
-PluginViewAndroid* PluginViewAndroid::currentPluginView()
-{
- return s_currentPluginView;
-}
-
-static char* createUTF8String(const String& str)
-{
- CString cstr = str.utf8();
- char* result = reinterpret_cast<char*>(fastMalloc(cstr.length() + 1));
-
- strncpy(result, cstr.data(), cstr.length() + 1);
-
- return result;
-}
-
-static void freeStringArray(char** stringArray, int length)
-{
- if (!stringArray)
- return;
-
- for (int i = 0; i < length; i++)
- fastFree(stringArray[i]);
-
- fastFree(stringArray);
-}
-
-NPError PluginViewAndroid::getURLNotify(const char* url,
- const char* target,
- void* notifyData)
-{
- notImplemented();
- return NPERR_GENERIC_ERROR;
-}
-
-NPError PluginViewAndroid::getURL(const char* url, const char* target)
-{
- notImplemented();
- return NPERR_GENERIC_ERROR;
-}
-
-NPError PluginViewAndroid::postURLNotify(const char* url,
- const char* target,
- uint32 len,
- const char* buf,
- NPBool file,
- void* notifyData)
-{
- notImplemented();
- return NPERR_GENERIC_ERROR;
-}
-
-NPError PluginViewAndroid::postURL(const char* url,
- const char* target,
- uint32 len,
- const char* buf,
- NPBool file)
-{
- notImplemented();
- return NPERR_GENERIC_ERROR;
-}
-
-NPError PluginViewAndroid::newStream(NPMIMEType type,
- const char* target,
- NPStream** stream)
-{
- notImplemented();
- return NPERR_GENERIC_ERROR;
-}
-
-int32 PluginViewAndroid::write(NPStream* stream,
- int32 len,
- void* buffer)
-{
- notImplemented();
- return -1;
-}
-
-NPError PluginViewAndroid::destroyStream(NPStream* stream, NPReason reason)
-{
- notImplemented();
- return NPERR_GENERIC_ERROR;
-}
-
-const char* PluginViewAndroid::userAgent()
-{
- if (m_userAgent.isNull())
- m_userAgent = m_parentFrame->loader()->userAgent(m_url).utf8();
- return m_userAgent.data();
-}
-
-void PluginViewAndroid::status(const char* message)
-{
- String s = DeprecatedString::fromLatin1(message);
-
- if (Page* page = m_parentFrame->page())
- page->chrome()->setStatusbarText(m_parentFrame, s);
-}
-
-NPError PluginViewAndroid::getValue(NPNVariable variable, void* value)
-{
- switch (variable) {
- case NPNVWindowNPObject: {
- NPObject* windowScriptObject =
- m_parentFrame->windowScriptNPObject();
-
- // Return value is expected to be retained, as described
- // here:
- // <http://www.mozilla.org/projects/plugin/npruntime.html>
- if (windowScriptObject)
- _NPN_RetainObject(windowScriptObject);
-
- void** v = (void**)value;
- *v = windowScriptObject;
-
- return NPERR_NO_ERROR;
- }
-
- case NPNVPluginElementNPObject: {
- NPObject* pluginScriptObject = 0;
-
- if (m_element->hasTagName(appletTag) ||
- m_element->hasTagName(embedTag) ||
- m_element->hasTagName(objectTag)) {
- HTMLPlugInElement* pluginElement =
- static_cast<HTMLPlugInElement*>(m_element);
- pluginScriptObject = pluginElement->getNPObject();
- }
-
- // Return value is expected to be retained, as described
- // here:
- // <http://www.mozilla.org/projects/plugin/npruntime.html>
- if (pluginScriptObject)
- _NPN_RetainObject(pluginScriptObject);
-
- void** v = (void**)value;
- *v = pluginScriptObject;
-
- return NPERR_NO_ERROR;
- }
-
- case NPNVnetscapeWindow: {
- // Return the top level WebView Java object associated
- // with this instance.
- jobject *retObject = static_cast<jobject*>(value);
- // Dig down through to the parent frame's WebCoreViewBridge
- FrameView* frameView = m_parentFrame->view();
- WebCoreViewBridge* bridge = frameView->getWebCoreViewBridge();
- // Go up parents until we reach the top level.
- while (bridge->getParent() != NULL)
- bridge = bridge->getParent();
- // This is actually an instance of WebCoreView.
- android::WebViewCore* webViewCore =
- static_cast<android::WebViewCore*>(bridge);
- // Finally, get hold of the Java WebView instance.
- *retObject = webViewCore->getWebViewJavaObject();
- return NPERR_NO_ERROR;
- }
- default:
- return NPERR_GENERIC_ERROR;
- }
-}
-
-NPError PluginViewAndroid::setValue(NPPVariable variable, void* value)
-{
- switch (variable) {
- case NPPVpluginWindowBool:
- m_isWindowed = value;
- return NPERR_NO_ERROR;
- case NPPVpluginTransparentBool:
- m_isTransparent = value;
- return NPERR_NO_ERROR;
- default:
- notImplemented();
- return NPERR_GENERIC_ERROR;
- }
-}
-
-void PluginViewAndroid::invalidateRect(NPRect* rect)
-{
- notImplemented();
-}
-
-void PluginViewAndroid::invalidateRegion(NPRegion region)
-{
- notImplemented();
-}
-
-void PluginViewAndroid::forceRedraw()
-{
- notImplemented();
-}
-
-KJS::Bindings::Instance* PluginViewAndroid::bindingInstance()
-{
- NPObject* object = 0;
-
- if (!m_plugin || !m_plugin->pluginFuncs()->getvalue)
- return 0;
-
- NPError npErr;
- {
- KJS::JSLock::DropAllLocks dropAllLocks;
- npErr = m_plugin->pluginFuncs()->getvalue(m_instance,
- NPPVpluginScriptableNPObject,
- &object);
- }
-
- if (npErr != NPERR_NO_ERROR || !object)
- return 0;
-
- RefPtr<KJS::Bindings::RootObject> root = m_parentFrame->createRootObject(
- this,
- m_parentFrame->scriptProxy()->globalObject());
- KJS::Bindings::Instance *instance =
- KJS::Bindings::Instance::createBindingForLanguageInstance(
- KJS::Bindings::Instance::CLanguage,
- object,
- root.release());
-
- _NPN_ReleaseObject(object);
-
- return instance;
-}
-
-PluginViewAndroid::~PluginViewAndroid()
-{
- stop();
-
- freeStringArray(m_paramNames, m_paramCount);
- freeStringArray(m_paramValues, m_paramCount);
-
- m_parentFrame->cleanupScriptObjectsForPlugin(this);
-
- // Don't unload the plugin - let the reference count clean it up.
-
- // Can't use RefPtr<> because it's name clashing with SkRefCnt<>
- m_viewBridge->unref();
-}
-
-void PluginViewAndroid::setParameters(const Vector<String>& paramNames,
- const Vector<String>& paramValues)
-{
- ASSERT(paramNames.size() == paramValues.size());
-
- // Also pass an extra parameter
- unsigned size = paramNames.size() + 1;
- unsigned paramCount = 0;
-
- m_paramNames = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size));
- m_paramValues = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size));
-
- for (unsigned i = 0; i < paramNames.size(); i++) {
- if (equalIgnoringCase(paramNames[i], "windowlessvideo"))
- continue;
- // Don't let the HTML element specify this value!
- if (equalIgnoringCase(paramNames[i], "android_plugins_dir"))
- continue;
-
- m_paramNames[paramCount] = createUTF8String(paramNames[i]);
- m_paramValues[paramCount] = createUTF8String(paramValues[i]);
-
- paramCount++;
- }
-
- // Pass the location of the plug-ins directory so the plug-in
- // knows where it can store any data it needs.
- WebCore::String path = m_parentFrame->settings()->pluginsPath();
- m_paramNames[paramCount] = createUTF8String("android_plugins_dir");
- m_paramValues[paramCount] = createUTF8String(path.utf8().data());
- paramCount++;
-
- m_paramCount = paramCount;
-}
-
-PluginViewAndroid::PluginViewAndroid(Frame* parentFrame,
- const IntSize& size,
- PluginPackageAndroid* plugin,
- Element* element,
- const KURL& url,
- const Vector<String>& paramNames,
- const Vector<String>& paramValues,
- const String& mimeType,
- bool loadManually)
- : m_plugin(plugin)
- , m_element(element)
- , m_parentFrame(parentFrame)
- , m_userAgent()
- , m_isStarted(false)
- , m_url(url)
- , m_status(PluginStatusLoadedSuccessfully)
- , m_mode(0)
- , m_paramCount(0)
- , m_paramNames(0)
- , m_paramValues(0)
- , m_mimeType()
- , m_instance()
- , m_instanceStruct()
- , m_isWindowed(true)
- , m_isTransparent(false)
- , m_haveInitialized(false)
- , m_lastMessage(0)
- , m_loadManually(loadManually)
- , m_viewBridge(new PluginViewBridgeAndroid())
-{
- setWebCoreViewBridge(m_viewBridge);
-
- if (!m_plugin) {
- m_status = PluginStatusCanNotFindPlugin;
- return;
- }
-
- m_instance = &m_instanceStruct;
- m_instance->ndata = this;
-
- m_mimeType = mimeType.utf8();
-
- setParameters(paramNames, paramValues);
-
- m_mode = m_loadManually ? NP_FULL : NP_EMBED;
-
- resize(size);
-
- // Early initialisation until we can properly parent this
- init();
-}
-
-void PluginViewAndroid::init()
-{
- if (m_haveInitialized)
- return;
- m_haveInitialized = true;
-
- if (!m_plugin) {
- ASSERT(m_status == PluginStatusCanNotFindPlugin);
- return;
- }
-
- if (!m_plugin->load()) {
- m_plugin = 0;
- m_status = PluginStatusCanNotLoadPlugin;
- return;
- }
-
- if (!start()) {
- m_status = PluginStatusCanNotLoadPlugin;
- return;
- }
-
- m_status = PluginStatusLoadedSuccessfully;
-}
-
-PluginViewBridgeAndroid::PluginViewBridgeAndroid()
-{
- m_image = Image::loadPlatformResource("nullplugin");
- if(m_image)
- setSize(m_image->width(), m_image->height());
- else
- PLUGIN_LOG("Couldn't get nullplugin image\n");
-}
-
-PluginViewBridgeAndroid::~PluginViewBridgeAndroid()
-{
- delete m_image;
-}
-
-void PluginViewBridgeAndroid::draw(GraphicsContext* gc,
- const IntRect& rect,
- bool)
-{
- if (gc->paintingDisabled() || !m_image)
- return;
-
- // Clip the drawing rectangle to our bounds in case it is larger.
- IntRect transRect(rect);
- IntRect bounds = this->getBounds();
- transRect.intersect(bounds);
-
- // Move the drawing rectangle into our coordinate space.
- transRect.move(-bounds.x(), -bounds.y());
-
- // Translate the canvas by the view's location so that things will draw
- // in the right place. Clip the canvas to the drawing rectangle.
- SkRect r;
- android_setrect(&r, transRect);
- if (r.isEmpty())
- return;
- SkCanvas* canvas = gc->platformContext()->mCanvas;
- canvas->save();
- canvas->translate(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()));
- canvas->clipRect(r);
-
- // Calculate where to place the image so it appears in the center of the
- // view.
- int imageWidth = m_image->width();
- int imageHeight = m_image->height();
- IntRect centerRect(0, 0, imageWidth, imageHeight);
- IntSize c1(bounds.width()/2, bounds.height()/2);
- IntSize c2(centerRect.width()/2, centerRect.height()/2);
- IntSize diff = c1 - c2;
- centerRect.move(diff);
-
- // Now move the top-left corner of the image to the top-left corner of
- // the view so that the tiling will hit the center image.
- while (diff.width() > 0)
- diff.setWidth(diff.width() - imageWidth);
- while (diff.height() > 0)
- diff.setHeight(diff.height() - imageHeight);
-
- // Draw the tiled transparent image adding one extra image width and
- // height so that we get a complete fill.
- gc->beginTransparencyLayer(0.1);
- gc->drawTiledImage(m_image,
- IntRect(diff.width(), diff.height(),
- bounds.width() + imageWidth,
- bounds.height() + imageHeight),
- IntPoint(0, 0), IntSize(imageWidth, imageHeight));
- gc->endTransparencyLayer();
-
- // Draw the image in the center.
- gc->drawImage(m_image, centerRect);
-
- // Restore our canvas
- canvas->restore();
-}
-
-} // namespace WebCore
-
-#endif // defined(ANDROID_PLUGINS)
diff --git a/WebCore/plugins/android/PluginViewAndroid.h b/WebCore/plugins/android/PluginViewAndroid.h
deleted file mode 100644
index d4e55b8..0000000
--- a/WebCore/plugins/android/PluginViewAndroid.h
+++ /dev/null
@@ -1,176 +0,0 @@
-#ifdef ANDROID_PLUGINS
-
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PluginViewAndroid_H
-#define PluginViewAndroid_H
-
-#include "CString.h"
-#include "IntRect.h"
-#include "KURL.h"
-#include "PlatformString.h"
-#include "ResourceRequest.h"
-#include "Widget.h"
-#include "npapi.h"
-#include "WebCoreViewBridge.h"
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-
-namespace KJS {
- namespace Bindings {
- class Instance;
- }
-}
-
-namespace WebCore {
- class Element;
- class Frame;
- class Image;
- class KURL;
- class PluginPackageAndroid;
-
- enum PluginStatus {
- PluginStatusCanNotFindPlugin,
- PluginStatusCanNotLoadPlugin,
- PluginStatusLoadedSuccessfully
- };
-
- class PluginViewBridgeAndroid : public WebCoreViewBridge {
- public:
- PluginViewBridgeAndroid();
- ~PluginViewBridgeAndroid();
- virtual void draw(GraphicsContext* gc, const IntRect& rect, bool);
- private:
- Image* m_image;
- };
-
- class PluginViewAndroid : public Widget {
- public:
- PluginViewAndroid(Frame* parentFrame,
- const IntSize&,
- PluginPackageAndroid* plugin,
- Element*,
- const KURL&,
- const Vector<String>& paramNames,
- const Vector<String>& paramValues,
- const String& mimeType,
- bool loadManually);
- virtual ~PluginViewAndroid();
-
- PluginPackageAndroid* plugin() const { return m_plugin.get(); }
- NPP instance() const { return m_instance; }
-
- static PluginViewAndroid* currentPluginView();
-
- KJS::Bindings::Instance* bindingInstance();
-
- PluginStatus status() const { return m_status; }
-
- // NPN stream functions
- NPError getURLNotify(const char* url,
- const char* target,
- void* notifyData);
- NPError getURL(const char* url,
- const char* target);
- NPError postURLNotify(const char* url,
- const char* target,
- uint32 len,
- const char* but,
- NPBool file,
- void* notifyData);
- NPError postURL(const char* url,
- const char* target,
- uint32 len,
- const char* but,
- NPBool file);
- NPError newStream(NPMIMEType type,
- const char* target,
- NPStream** stream);
- int32 write(NPStream* stream, int32 len, void* buffer);
- NPError destroyStream(NPStream* stream, NPReason reason);
-
- // NPN misc functions
- const char* userAgent();
- void status(const char* message);
- NPError getValue(NPNVariable variable, void* value);
- NPError setValue(NPPVariable variable, void* value);
-
- // NPN UI functions
- void invalidateRect(NPRect*);
- void invalidateRegion(NPRegion);
- void forceRedraw();
-
- // Widget functions
- virtual void setParent(ScrollView*);
-
- private:
- void setParameters(const Vector<String>& paramNames,
- const Vector<String>& paramValues);
- void init();
- bool start();
- void stop();
- static void setCurrentPluginView(PluginViewAndroid*);
-
- // Maintain a refcount on the plugin. It should be deleted
- // once all views no longer reference it.
- RefPtr<PluginPackageAndroid> m_plugin;
- Element* m_element;
- Frame* m_parentFrame;
- CString m_userAgent;
- bool m_isStarted;
- KURL m_url;
- PluginStatus m_status;
-
- int m_mode;
- int m_paramCount;
- char** m_paramNames;
- char** m_paramValues;
-
- CString m_mimeType;
- NPP m_instance;
- NPP_t m_instanceStruct;
-
- bool m_isWindowed;
- bool m_isTransparent;
- bool m_haveInitialized;
-
- unsigned m_lastMessage;
-
- bool m_loadManually;
-
- // Sorry, can't use RefPtr<> due to name collision with SkRefCnt.
- PluginViewBridgeAndroid *m_viewBridge;
-
- static PluginViewAndroid* s_currentPluginView;
- };
-
-} // namespace WebCore
-
-#endif
-
-#endif // defined(ANDROID_PLUGINS)
diff --git a/WebCore/plugins/android/npapi.cpp b/WebCore/plugins/android/npapi.cpp
deleted file mode 100644
index 23007eb..0000000
--- a/WebCore/plugins/android/npapi.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifdef ANDROID_PLUGINS
-// Needed for NPN_PluginThreadAsyncCall, which calls
-// JavaSharedClient::EnqueueFunctionPtr().
-#include "JavaSharedClient.h"
-#endif
-#include "WebCoreJni.h"
-#include "PluginInfoStore.h"
-#include "PluginViewAndroid.h"
-#include "jni.h"
-#include "npapi.h"
-
-#include "PluginDebug.h"
-
-using namespace WebCore;
-
-// The plugin view is always the ndata of the instance,. Sometimes, plug-ins will call an instance-specific function
-// with a NULL instance. To workaround this, call the last plug-in view that made a call to a plug-in.
-// Currently, the current plug-in view is only set before NPP_New in PluginViewAndroid::start.
-// This specifically works around Flash and Shockwave. When we call NPP_New, they call NPN_Useragent with a NULL instance.
-static PluginViewAndroid* pluginViewForInstance(NPP instance)
-{
- if (instance && instance->ndata)
- return static_cast<PluginViewAndroid*>(instance->ndata);
- return PluginViewAndroid::currentPluginView();
-}
-
-void* NPN_MemAlloc(uint32 size)
-{
- return malloc(size);
-}
-
-void NPN_MemFree(void* ptr)
-{
- free(ptr);
-}
-
-uint32 NPN_MemFlush(uint32 size)
-{
- // Do nothing
- return 0;
-}
-
-void NPN_ReloadPlugins(NPBool reloadPages)
-{
- refreshPlugins(reloadPages);
-}
-
-NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
-{
- return NPERR_STREAM_NOT_SEEKABLE;
-}
-
-NPError NPN_GetURLNotify(NPP instance, const char* url, const char* target, void* notifyData)
-{
- return pluginViewForInstance(instance)->getURLNotify(url, target, notifyData);
-}
-
-NPError NPN_GetURL(NPP instance, const char* url, const char* target)
-{
- return pluginViewForInstance(instance)->getURL(url, target);
-}
-
-NPError NPN_PostURLNotify(NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData)
-{
- return pluginViewForInstance(instance)->postURLNotify(url, target, len, buf, file, notifyData);
-}
-
-NPError NPN_PostURL(NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file)
-{
- return pluginViewForInstance(instance)->postURL(url, target, len, buf, file);
-}
-
-NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream)
-{
- return pluginViewForInstance(instance)->newStream(type, target, stream);
-}
-
-int32 NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
-{
- return pluginViewForInstance(instance)->write(stream, len, buffer);
-}
-
-NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
-{
- return pluginViewForInstance(instance)->destroyStream(stream, reason);
-}
-
-const char* NPN_UserAgent(NPP instance)
-{
- PluginViewAndroid* view = pluginViewForInstance(instance);
-
- // FIXME: Some plug-ins call NPN_UserAgent with a null instance in their NP_initialize function!
- // We'd need a way to get a user agent without having a frame around.
- if (!view)
- return 0;
-
- return view->userAgent();
-}
-
-void NPN_Status(NPP instance, const char* message)
-{
- pluginViewForInstance(instance)->status(message);
-}
-
-void NPN_InvalidateRect(NPP instance, NPRect* invalidRect)
-{
- pluginViewForInstance(instance)->invalidateRect(invalidRect);
-}
-
-void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion)
-{
- pluginViewForInstance(instance)->invalidateRegion(invalidRegion);
-}
-
-void NPN_ForceRedraw(NPP instance)
-{
- pluginViewForInstance(instance)->forceRedraw();
-}
-
-NPError NPN_GetValue(NPP instance, NPNVariable variable, void* value)
-{
- return pluginViewForInstance(instance)->getValue(variable, value);
-}
-
-NPError NPN_SetValue(NPP instance, NPPVariable variable, void* value)
-{
- return pluginViewForInstance(instance)->setValue(variable, value);
-}
-
-void* NPN_GetJavaEnv()
-{
- // This is supposed to return the JRIEnv, but nobody's been using
- // that interface for years. Far more useful to return the JNIEnv,
- // so we'll do that...
- JNIEnv* env = NULL;
- if (android::WebCoreJni::getJavaVM()->GetEnv((void**) &env,
- JNI_VERSION_1_4) != JNI_OK) {
- PLUGIN_LOG("GetEnv failed!");
- }
- return env;
-}
-
-void* NPN_GetJavaPeer(NPP instance)
-{
- // Unsupported
- return 0;
-}
-
-void
-NPN_PushPopupsEnabledState(NPP instance, NPBool enabled)
-{
-}
-
-void
-NPN_PopPopupsEnabledState(NPP instance)
-{
-}
-
-#ifdef ANDROID_PLUGINS
-// Added in version 19 NPAPI. Sandbox WebKit has this same function in
-// plugins/npapi.cpp rather than plugins/android/npapi.cpp. This file
-// goes away after merge.
-void NPN_PluginThreadAsyncCall(NPP instance,
- void (*func)(void *),
- void *userData)
-{
- // This is used to marshal a function call onto the main thread,
- // so plugins can get around not "owning" the message loop. Note
- // that the plugin is responsible for taking care of the potential
- // race between the order of NPP_Destroy and callbacks.
- JavaSharedClient::EnqueueFunctionPtr(func, userData);
-}
-#endif
diff --git a/WebCore/plugins/android/npfunctions.h b/WebCore/plugins/android/npfunctions.h
deleted file mode 100644
index f9a5612..0000000
--- a/WebCore/plugins/android/npfunctions.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _NPFUNCTIONS_H_
-#define _NPFUNCTIONS_H_
-
-#include <jni.h>
-#include "npruntime.h"
-#include "npapi.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(XP_WIN)
-#define EXPORTED_CALLBACK(_type, _name) _type (__stdcall * _name)
-#else
-#define EXPORTED_CALLBACK(_type, _name) _type (* _name)
-#endif
-
-typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* URL, const char* window, void* notifyData);
-typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* URL, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData);
-typedef NPError (*NPN_RequestReadProcPtr)(NPStream* stream, NPByteRange* rangeList);
-typedef NPError (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type, const char* window, NPStream** stream);
-typedef int32 (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32 len, void* buffer);
-typedef NPError (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
-typedef void (*NPN_StatusProcPtr)(NPP instance, const char* message);
-typedef const char*(*NPN_UserAgentProcPtr)(NPP instance);
-typedef void* (*NPN_MemAllocProcPtr)(uint32 size);
-typedef void (*NPN_MemFreeProcPtr)(void* ptr);
-typedef uint32 (*NPN_MemFlushProcPtr)(uint32 size);
-typedef void (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages);
-typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value);
-typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value);
-typedef void (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect *rect);
-typedef void (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region);
-typedef void (*NPN_ForceRedrawProcPtr)(NPP instance);
-typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* URL, const char* window);
-typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* URL, const char* window, uint32 len, const char* buf, NPBool file);
-typedef void* (*NPN_GetJavaEnvProcPtr)(void);
-typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
-typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP instance, NPBool enabled);
-typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP instance);
-
-typedef void (*NPN_ReleaseVariantValueProcPtr) (NPVariant *variant);
-
-typedef NPIdentifier (*NPN_GetStringIdentifierProcPtr) (const NPUTF8 *name);
-typedef void (*NPN_GetStringIdentifiersProcPtr) (const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers);
-typedef NPIdentifier (*NPN_GetIntIdentifierProcPtr) (int32_t intid);
-typedef int32_t (*NPN_IntFromIdentifierProcPtr) (NPIdentifier identifier);
-typedef bool (*NPN_IdentifierIsStringProcPtr) (NPIdentifier identifier);
-typedef NPUTF8 *(*NPN_UTF8FromIdentifierProcPtr) (NPIdentifier identifier);
-
-typedef NPObject* (*NPN_CreateObjectProcPtr) (NPP, NPClass *aClass);
-typedef NPObject* (*NPN_RetainObjectProcPtr) (NPObject *obj);
-typedef void (*NPN_ReleaseObjectProcPtr) (NPObject *obj);
-typedef bool (*NPN_InvokeProcPtr) (NPP npp, NPObject *obj, NPIdentifier methodName, const NPVariant *args, unsigned argCount, NPVariant *result);
-typedef bool (*NPN_InvokeDefaultProcPtr) (NPP npp, NPObject *obj, const NPVariant *args, unsigned argCount, NPVariant *result);
-typedef bool (*NPN_EvaluateProcPtr) (NPP npp, NPObject *obj, NPString *script, NPVariant *result);
-typedef bool (*NPN_GetPropertyProcPtr) (NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result);
-typedef bool (*NPN_SetPropertyProcPtr) (NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value);
-typedef bool (*NPN_HasPropertyProcPtr) (NPP, NPObject *npobj, NPIdentifier propertyName);
-typedef bool (*NPN_HasMethodProcPtr) (NPP npp, NPObject *npobj, NPIdentifier methodName);
-typedef bool (*NPN_RemovePropertyProcPtr) (NPP npp, NPObject *obj, NPIdentifier propertyName);
-typedef void (*NPN_SetExceptionProcPtr) (NPObject *obj, const NPUTF8 *message);
-typedef bool (*NPN_EnumerateProcPtr) (NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count);
-#ifdef ANDROID_PLUGINS
-// Added in version 19 NPAPI. Sandbox WebKit is version 20 and already
-// implements this change.
-typedef void (*NPN_PluginThreadAsyncCallPtr) (NPP npp, void (*func)(void *), void *userData);
-#endif
-
-typedef NPError (*NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved);
-typedef NPError (*NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
-typedef NPError (*NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
-typedef NPError (*NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype);
-typedef NPError (*NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason);
-typedef void (*NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream, const char* fname);
-typedef int32 (*NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream);
-typedef int32 (*NPP_WriteProcPtr)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer);
-typedef void (*NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint);
-typedef int16 (*NPP_HandleEventProcPtr)(NPP instance, void* event);
-typedef void (*NPP_URLNotifyProcPtr)(NPP instance, const char* URL, NPReason reason, void* notifyData);
-typedef NPError (*NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
-typedef NPError (*NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);
-typedef EXPORTED_CALLBACK(void, NPP_ShutdownProcPtr)(void);
-
-typedef void *(*NPP_GetJavaClassProcPtr)(void);
-typedef void* JRIGlobalRef; //not using this right now
-
-typedef struct _NPNetscapeFuncs {
- uint16 size;
- uint16 version;
-
- NPN_GetURLProcPtr geturl;
- NPN_PostURLProcPtr posturl;
- NPN_RequestReadProcPtr requestread;
- NPN_NewStreamProcPtr newstream;
- NPN_WriteProcPtr write;
- NPN_DestroyStreamProcPtr destroystream;
- NPN_StatusProcPtr status;
- NPN_UserAgentProcPtr uagent;
- NPN_MemAllocProcPtr memalloc;
- NPN_MemFreeProcPtr memfree;
- NPN_MemFlushProcPtr memflush;
- NPN_ReloadPluginsProcPtr reloadplugins;
- NPN_GetJavaEnvProcPtr getJavaEnv;
- NPN_GetJavaPeerProcPtr getJavaPeer;
- NPN_GetURLNotifyProcPtr geturlnotify;
- NPN_PostURLNotifyProcPtr posturlnotify;
- NPN_GetValueProcPtr getvalue;
- NPN_SetValueProcPtr setvalue;
- NPN_InvalidateRectProcPtr invalidaterect;
- NPN_InvalidateRegionProcPtr invalidateregion;
- NPN_ForceRedrawProcPtr forceredraw;
-
- NPN_GetStringIdentifierProcPtr getstringidentifier;
- NPN_GetStringIdentifiersProcPtr getstringidentifiers;
- NPN_GetIntIdentifierProcPtr getintidentifier;
- NPN_IdentifierIsStringProcPtr identifierisstring;
- NPN_UTF8FromIdentifierProcPtr utf8fromidentifier;
- NPN_IntFromIdentifierProcPtr intfromidentifier;
- NPN_CreateObjectProcPtr createobject;
- NPN_RetainObjectProcPtr retainobject;
- NPN_ReleaseObjectProcPtr releaseobject;
- NPN_InvokeProcPtr invoke;
- NPN_InvokeDefaultProcPtr invokeDefault;
- NPN_EvaluateProcPtr evaluate;
- NPN_GetPropertyProcPtr getproperty;
- NPN_SetPropertyProcPtr setproperty;
- NPN_RemovePropertyProcPtr removeproperty;
- NPN_HasPropertyProcPtr hasproperty;
- NPN_HasMethodProcPtr hasmethod;
- NPN_ReleaseVariantValueProcPtr releasevariantvalue;
- NPN_SetExceptionProcPtr setexception;
- NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
- NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
- NPN_EnumerateProcPtr enumerate;
-#ifdef ANDROID_PLUGINS
- // Added in version 19 NPAPI. Sandbox WebKit is version 20 and
- // already implements this change.
- NPN_PluginThreadAsyncCallPtr pluginthreadasynccall;
-#endif
-} NPNetscapeFuncs;
-
-typedef struct _NPPluginFuncs {
- uint16 size;
- uint16 version;
- NPP_NewProcPtr newp;
- NPP_DestroyProcPtr destroy;
- NPP_SetWindowProcPtr setwindow;
- NPP_NewStreamProcPtr newstream;
- NPP_DestroyStreamProcPtr destroystream;
- NPP_StreamAsFileProcPtr asfile;
- NPP_WriteReadyProcPtr writeready;
- NPP_WriteProcPtr write;
- NPP_PrintProcPtr print;
- NPP_HandleEventProcPtr event;
- NPP_URLNotifyProcPtr urlnotify;
- JRIGlobalRef javaClass;
- NPP_GetValueProcPtr getvalue;
- NPP_SetValueProcPtr setvalue;
-} NPPluginFuncs;
-
-typedef NPError (*NP_InitializeFuncPtr)(NPNetscapeFuncs *netscape_funcs,
- NPPluginFuncs *plugin_funcs,
- JNIEnv *java_environment,
- jobject application_context);
-typedef NPError (*NP_ShutdownFuncPtr)();
-typedef char* (*NP_GetMIMEDescriptionFuncPtr)();
-typedef NPError (*NP_GetValueFuncPtr)(void *instance,
- NPPVariable var,
- void *value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/WebCore/plugins/gtk/PluginDataGtk.cpp b/WebCore/plugins/gtk/PluginDataGtk.cpp
new file mode 100644
index 0000000..0d477cd
--- /dev/null
+++ b/WebCore/plugins/gtk/PluginDataGtk.cpp
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2008 Collabora Ltd. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "PluginData.h"
+
+#include "PluginDatabase.h"
+#include "PluginPackage.h"
+#include <stdio.h>
+namespace WebCore {
+
+void PluginData::initPlugins()
+{
+ PluginDatabase *db = PluginDatabase::installedPlugins();
+ const Vector<PluginPackage*> &plugins = db->plugins();
+
+ for (unsigned int i = 0; i < plugins.size(); ++i) {
+ PluginInfo* info = new PluginInfo;
+ PluginPackage* package = plugins[i];
+
+ info->name = package->name();
+ info->file = package->fileName();
+ info->desc = package->description();
+
+ const MIMEToDescriptionsMap& mimeToDescriptions = package->mimeToDescriptions();
+ MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end();
+ for (MIMEToDescriptionsMap::const_iterator it = mimeToDescriptions.begin(); it != end; ++it) {
+ MimeClassInfo* mime = new MimeClassInfo;
+ info->mimes.append(mime);
+
+ mime->type = it->first;
+ mime->desc = it->second;
+ mime->plugin = info;
+
+ Vector<String> extensions = package->mimeToExtensions().get(mime->type);
+
+ for (unsigned i = 0; i < extensions.size(); i++) {
+ if (i > 0)
+ mime->suffixes += ",";
+
+ mime->suffixes += extensions[i];
+ }
+ }
+
+ m_plugins.append(info);
+ }
+}
+
+void PluginData::refresh()
+{
+ PluginDatabase *db = PluginDatabase::installedPlugins();
+ db->refresh();
+}
+
+};
diff --git a/WebCore/plugins/gtk/PluginPackageGtk.cpp b/WebCore/plugins/gtk/PluginPackageGtk.cpp
new file mode 100644
index 0000000..5a097b2
--- /dev/null
+++ b/WebCore/plugins/gtk/PluginPackageGtk.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
+ * Copyright (C) 2008 Nuanti Ltd.
+ * Copyright (C) 2008 Novell Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginPackage.h"
+
+#include "CString.h"
+#include "MIMETypeRegistry.h"
+#include "NotImplemented.h"
+#include "npruntime_impl.h"
+#include "PluginDebug.h"
+
+namespace WebCore {
+
+static PlatformModuleVersion getModuleVersion(const char *description)
+{
+ // It's a bit lame to detect the plugin version by parsing it
+ // from the plugin description string, but it doesn't seem that
+ // version information is available in any standardized way at
+ // the module level, like in Windows
+
+ PlatformModuleVersion version = 0;
+
+ if (!description)
+ return 0;
+
+ if (g_str_has_prefix(description, "Shockwave Flash ") && strlen(description) >= 19) {
+ // The flash version as a PlatformModuleVersion differs in GTK from Windows
+ // since the revision can be larger than a 8 bits, so we allow it 16 here and
+ // push the major/minor up 8 bits. Thus in GTK, Flash's version may be
+ // 0x0a000000 instead of 0x000a0000. This avoids having to modify
+ // PlatformModuleVersion in the GTK port
+
+ char **version_parts = g_strsplit(description + 16, " ", -1);
+ if (!version_parts)
+ return 0;
+
+ int parts_length = g_strv_length(version_parts);
+
+ if (parts_length >= 1) {
+ guint16 major = 0, minor = 0;
+ if (sscanf(version_parts[0], "%" G_GUINT16_FORMAT ".%" G_GUINT16_FORMAT, &major, &minor) == 2)
+ version = ((guint8)major << 24) | ((guint8)minor << 16);
+ }
+
+ if (parts_length >= 2) {
+ char *rev_str = version_parts[1];
+ if (strlen(rev_str) > 1 && (rev_str[0] == 'r' || rev_str[0] == 'b'))
+ version |= (guint16)atoi(rev_str + 1);
+ }
+
+ g_strfreev(version_parts);
+ }
+
+ return version;
+}
+
+void PluginPackage::determineQuirks(const String& mimeType)
+{
+ if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) {
+ // Because a single process cannot create multiple VMs, and we cannot reliably unload a
+ // Java VM, we cannot unload the Java plugin, or we'll lose reference to our only VM
+ m_quirks.add(PluginQuirkDontUnloadPlugin);
+
+ // Setting the window region to an empty region causes bad scrolling repaint problems
+ // with the Java plug-in.
+ m_quirks.add(PluginQuirkDontClipToZeroRectWhenScrolling);
+ return;
+ }
+
+ if (mimeType == "application/x-shockwave-flash") {
+ static const PlatformModuleVersion flashTenVersion(0x0a000000);
+
+ if (compareFileVersion(flashTenVersion) >= 0) {
+ // Flash 10.0 b218 doesn't like having a NULL window handle
+ m_quirks.add(PluginQuirkDontSetNullWindowHandleOnDestroy);
+ } else {
+ // Flash 9 and older requests windowless plugins if we return a mozilla user agent
+ m_quirks.add(PluginQuirkWantsMozillaUserAgent);
+ }
+
+ m_quirks.add(PluginQuirkThrottleInvalidate);
+ m_quirks.add(PluginQuirkThrottleWMUserPlusOneMessages);
+ m_quirks.add(PluginQuirkFlashURLNotifyBug);
+ }
+}
+
+bool PluginPackage::fetchInfo()
+{
+#if defined(XP_UNIX)
+ if (!load())
+ return false;
+
+ NP_GetMIMEDescriptionFuncPtr NP_GetMIMEDescription;
+ NPP_GetValueProcPtr NPP_GetValue;
+
+ g_module_symbol(m_module, "NP_GetMIMEDescription", (void**)&NP_GetMIMEDescription);
+ g_module_symbol(m_module, "NP_GetValue", (void**)&NPP_GetValue);
+
+ char* buffer = 0;
+ NPError err = NPP_GetValue(0, NPPVpluginNameString, &buffer);
+ if (err == NPERR_NO_ERROR)
+ m_name = buffer;
+
+ buffer = 0;
+ err = NPP_GetValue(0, NPPVpluginDescriptionString, &buffer);
+ if (err == NPERR_NO_ERROR) {
+ m_description = buffer;
+ m_moduleVersion = getModuleVersion(buffer);
+ }
+
+ const gchar* types = NP_GetMIMEDescription();
+ gchar** mimeDescs = g_strsplit(types, ";", -1);
+ for (int i = 0; mimeDescs[i] && mimeDescs[i][0]; i++) {
+ gchar** mimeData = g_strsplit(mimeDescs[i], ":", 3);
+ if (g_strv_length(mimeData) < 3) {
+ g_strfreev(mimeData);
+ continue;
+ }
+
+ String description = String::fromUTF8(mimeData[2]);
+ gchar** extensions = g_strsplit(mimeData[1], ",", -1);
+
+ Vector<String> extVector;
+ for (int j = 0; extensions[j]; j++)
+ extVector.append(String::fromUTF8(extensions[j]));
+
+ determineQuirks(mimeData[0]);
+ m_mimeToExtensions.add(mimeData[0], extVector);
+ m_mimeToDescriptions.add(mimeData[0], description);
+
+ g_strfreev(extensions);
+ g_strfreev(mimeData);
+ }
+ g_strfreev(mimeDescs);
+
+ return true;
+#else
+ notImplemented();
+ return false;
+#endif
+}
+
+bool PluginPackage::load()
+{
+ if (m_isLoaded) {
+ m_loadCount++;
+ return true;
+ }
+
+ m_module = g_module_open((m_path.utf8()).data(), G_MODULE_BIND_LOCAL);
+
+ if (!m_module) {
+ LOG(Plugin,"Module Load Failed :%s, Error:%s\n", (m_path.utf8()).data(), g_module_error());
+ return false;
+ }
+
+ m_isLoaded = true;
+
+ NP_InitializeFuncPtr NP_Initialize;
+ NPError npErr;
+
+ g_module_symbol(m_module, "NP_Initialize", (void**)&NP_Initialize);
+ g_module_symbol(m_module, "NP_Shutdown", (void**)&m_NPP_Shutdown);
+
+ if (!NP_Initialize || !m_NPP_Shutdown)
+ goto abort;
+
+ memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
+ m_pluginFuncs.size = sizeof(m_pluginFuncs);
+
+ m_browserFuncs.size = sizeof (m_browserFuncs);
+ m_browserFuncs.version = NP_VERSION_MINOR;
+ m_browserFuncs.geturl = NPN_GetURL;
+ m_browserFuncs.posturl = NPN_PostURL;
+ m_browserFuncs.requestread = NPN_RequestRead;
+ m_browserFuncs.newstream = NPN_NewStream;
+ m_browserFuncs.write = NPN_Write;
+ m_browserFuncs.destroystream = NPN_DestroyStream;
+ m_browserFuncs.status = NPN_Status;
+ m_browserFuncs.uagent = NPN_UserAgent;
+ m_browserFuncs.memalloc = NPN_MemAlloc;
+ m_browserFuncs.memfree = NPN_MemFree;
+ m_browserFuncs.memflush = NPN_MemFlush;
+ m_browserFuncs.reloadplugins = NPN_ReloadPlugins;
+ m_browserFuncs.geturlnotify = NPN_GetURLNotify;
+ m_browserFuncs.posturlnotify = NPN_PostURLNotify;
+ m_browserFuncs.getvalue = NPN_GetValue;
+ m_browserFuncs.setvalue = NPN_SetValue;
+ m_browserFuncs.invalidaterect = NPN_InvalidateRect;
+ m_browserFuncs.invalidateregion = NPN_InvalidateRegion;
+ m_browserFuncs.forceredraw = NPN_ForceRedraw;
+ m_browserFuncs.getJavaEnv = NPN_GetJavaEnv;
+ m_browserFuncs.getJavaPeer = NPN_GetJavaPeer;
+ m_browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState;
+ m_browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState;
+
+ m_browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
+ m_browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
+ m_browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers;
+ m_browserFuncs.getintidentifier = _NPN_GetIntIdentifier;
+ m_browserFuncs.identifierisstring = _NPN_IdentifierIsString;
+ m_browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier;
+ m_browserFuncs.createobject = _NPN_CreateObject;
+ m_browserFuncs.retainobject = _NPN_RetainObject;
+ m_browserFuncs.releaseobject = _NPN_ReleaseObject;
+ m_browserFuncs.invoke = _NPN_Invoke;
+ m_browserFuncs.invokeDefault = _NPN_InvokeDefault;
+ m_browserFuncs.evaluate = _NPN_Evaluate;
+ m_browserFuncs.getproperty = _NPN_GetProperty;
+ m_browserFuncs.setproperty = _NPN_SetProperty;
+ m_browserFuncs.removeproperty = _NPN_RemoveProperty;
+ m_browserFuncs.hasproperty = _NPN_HasMethod;
+ m_browserFuncs.hasmethod = _NPN_HasProperty;
+ m_browserFuncs.setexception = _NPN_SetException;
+ m_browserFuncs.enumerate = _NPN_Enumerate;
+ m_browserFuncs.construct = _NPN_Construct;
+
+#if defined(XP_UNIX)
+ npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
+#else
+ npErr = NP_Initialize(&m_browserFuncs);
+#endif
+ if (npErr != NPERR_NO_ERROR)
+ goto abort;
+
+ m_loadCount++;
+ return true;
+
+abort:
+ unloadWithoutShutdown();
+ return false;
+}
+
+unsigned PluginPackage::hash() const
+{
+ unsigned hashCodes[2] = {
+ m_path.impl()->hash(),
+ m_lastModified
+ };
+
+ return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), 2 * sizeof(unsigned) / sizeof(UChar));
+}
+
+bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b)
+{
+ return a.m_description == b.m_description;
+}
+
+int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const
+{
+ // return -1, 0, or 1 if plug-in version is less than, equal to, or greater than
+ // the passed version
+ if (m_moduleVersion != compareVersion)
+ return m_moduleVersion > compareVersion ? 1 : -1;
+ return 0;
+}
+
+}
diff --git a/WebCore/plugins/gtk/PluginViewGtk.cpp b/WebCore/plugins/gtk/PluginViewGtk.cpp
new file mode 100644
index 0000000..904e935
--- /dev/null
+++ b/WebCore/plugins/gtk/PluginViewGtk.cpp
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginView.h"
+
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "Element.h"
+#include "FrameLoader.h"
+#include "FrameLoadRequest.h"
+#include "FrameTree.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "HTMLNames.h"
+#include "HTMLPlugInElement.h"
+#include "KeyboardEvent.h"
+#include "MouseEvent.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "PlatformMouseEvent.h"
+#include "PluginDebug.h"
+#include "PluginPackage.h"
+#include "RenderLayer.h"
+#include "Settings.h"
+#include "JSDOMBinding.h"
+#include "ScriptController.h"
+#include "npruntime_impl.h"
+#include "runtime.h"
+#include "runtime_root.h"
+#include <runtime/JSLock.h>
+#include <runtime/JSValue.h>
+
+#include <gdkconfig.h>
+#include <gtk/gtk.h>
+
+#if PLATFORM(X11)
+#include "gtk2xtbin.h"
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_WIN32
+#include "PluginMessageThrottlerWin.h"
+#include <gdk/gdkwin32.h>
+#endif
+
+using JSC::ExecState;
+using JSC::Interpreter;
+using JSC::JSLock;
+using JSC::JSObject;
+using JSC::UString;
+
+using std::min;
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+void PluginView::updatePluginWidget() const
+{
+ if (!parent() || !m_isWindowed)
+ return;
+
+ ASSERT(parent()->isFrameView());
+ FrameView* frameView = static_cast<FrameView*>(parent());
+
+ IntRect oldWindowRect = m_windowRect;
+ IntRect oldClipRect = m_clipRect;
+
+ m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size());
+ m_clipRect = windowClipRect();
+ m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
+
+ GtkAllocation allocation = { m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height() };
+ if (platformPluginWidget()) {
+ gtk_widget_size_allocate(platformPluginWidget(), &allocation);
+#if PLATFORM(X11)
+ if (!m_needsXEmbed) {
+ gtk_xtbin_set_position(GTK_XTBIN(platformPluginWidget()), m_windowRect.x(), m_windowRect.y());
+ gtk_xtbin_resize(platformPluginWidget(), m_windowRect.width(), m_windowRect.height());
+ }
+#endif
+ }
+}
+
+void PluginView::setFocus()
+{
+ if (platformPluginWidget())
+ gtk_widget_grab_focus(platformPluginWidget());
+
+ Widget::setFocus();
+}
+
+void PluginView::show()
+{
+ setSelfVisible(true);
+
+ if (isParentVisible() && platformPluginWidget())
+ gtk_widget_show(platformPluginWidget());
+
+ Widget::show();
+}
+
+void PluginView::hide()
+{
+ setSelfVisible(false);
+
+ if (isParentVisible() && platformPluginWidget())
+ gtk_widget_hide(platformPluginWidget());
+
+ Widget::hide();
+}
+
+void PluginView::paint(GraphicsContext* context, const IntRect& rect)
+{
+ if (!m_isStarted) {
+ // Draw the "missing plugin" image
+ //paintMissingPluginIcon(context, rect);
+ return;
+ }
+
+ if (m_isWindowed || context->paintingDisabled())
+ return;
+
+ NPEvent npEvent;
+ /* Need to synthesize Xevents here */
+
+ m_npWindow.type = NPWindowTypeDrawable;
+
+ ASSERT(parent()->isFrameView());
+
+ if (m_plugin->pluginFuncs()->event) {
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ m_plugin->pluginFuncs()->event(m_instance, &npEvent);
+ }
+
+ setNPWindowRect(frameRect());
+}
+
+void PluginView::handleKeyboardEvent(KeyboardEvent* event)
+{
+ NPEvent npEvent;
+
+ /* FIXME: Synthesize an XEvent to pass through */
+
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ if (!m_plugin->pluginFuncs()->event(m_instance, &npEvent))
+ event->setDefaultHandled();
+}
+
+void PluginView::handleMouseEvent(MouseEvent* event)
+{
+ NPEvent npEvent;
+
+ if (!m_isWindowed)
+ return;
+
+ /* FIXME: Synthesize an XEvent to pass through */
+ IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(IntPoint(event->pageX(), event->pageY()));
+
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ if (!m_plugin->pluginFuncs()->event(m_instance, &npEvent))
+ event->setDefaultHandled();
+}
+
+void PluginView::setParent(ScrollView* parent)
+{
+ Widget::setParent(parent);
+
+ if (parent)
+ init();
+ else {
+ if (!platformPluginWidget())
+ return;
+ }
+}
+
+void PluginView::setNPWindowRect(const IntRect& rect)
+{
+ if (!m_isStarted || !parent())
+ return;
+
+ IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(rect.location());
+ m_npWindow.x = p.x();
+ m_npWindow.y = p.y();
+
+ m_npWindow.width = rect.width();
+ m_npWindow.height = rect.height();
+
+ m_npWindow.clipRect.left = 0;
+ m_npWindow.clipRect.top = 0;
+ m_npWindow.clipRect.right = rect.width();
+ m_npWindow.clipRect.bottom = rect.height();
+
+ if (m_npWindow.x < 0 || m_npWindow.y < 0 ||
+ m_npWindow.width <= 0 || m_npWindow.height <= 0)
+ return;
+
+ if (m_plugin->pluginFuncs()->setwindow) {
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+
+ if (!m_isWindowed)
+ return;
+
+ ASSERT(platformPluginWidget());
+ }
+}
+
+void PluginView::setParentVisible(bool visible)
+{
+ if (isParentVisible() == visible)
+ return;
+
+ Widget::setParentVisible(visible);
+
+ if (isSelfVisible() && platformPluginWidget()) {
+ if (visible)
+ gtk_widget_show(platformPluginWidget());
+ else
+ gtk_widget_hide(platformPluginWidget());
+ }
+}
+
+void PluginView::stop()
+{
+ if (!m_isStarted)
+ return;
+
+ HashSet<RefPtr<PluginStream> > streams = m_streams;
+ HashSet<RefPtr<PluginStream> >::iterator end = streams.end();
+ for (HashSet<RefPtr<PluginStream> >::iterator it = streams.begin(); it != end; ++it) {
+ (*it)->stop();
+ disconnectStream((*it).get());
+ }
+
+ ASSERT(m_streams.isEmpty());
+
+ m_isStarted = false;
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+
+ // Clear the window
+ m_npWindow.window = 0;
+ if (m_plugin->pluginFuncs()->setwindow && !m_plugin->quirks().contains(PluginQuirkDontSetNullWindowHandleOnDestroy)) {
+ PluginView::setCurrentPluginView(this);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+
+#ifdef XP_UNIX
+ if (m_isWindowed && m_npWindow.ws_info)
+ delete (NPSetWindowCallbackStruct *)m_npWindow.ws_info;
+ m_npWindow.ws_info = 0;
+#endif
+
+ // Destroy the plugin
+ {
+ PluginView::setCurrentPluginView(this);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->destroy(m_instance, 0);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+
+ m_instance->pdata = 0;
+}
+
+static const char* MozillaUserAgent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0";
+
+const char* PluginView::userAgent()
+{
+ if (m_plugin->quirks().contains(PluginQuirkWantsMozillaUserAgent))
+ return MozillaUserAgent;
+
+ if (m_userAgent.isNull())
+ m_userAgent = m_parentFrame->loader()->userAgent(m_url).utf8();
+
+ return m_userAgent.data();
+}
+
+const char* PluginView::userAgentStatic()
+{
+ //FIXME - Lie and say we are Mozilla
+ return MozillaUserAgent;
+}
+
+NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf)
+{
+ String filename(buf, len);
+
+ if (filename.startsWith("file:///"))
+ filename = filename.substring(8);
+
+ // Get file info
+ if (!g_file_test ((filename.utf8()).data(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)))
+ return NPERR_FILE_NOT_FOUND;
+
+ //FIXME - read the file data into buffer
+ FILE* fileHandle = fopen((filename.utf8()).data(), "r");
+
+ if (fileHandle == 0)
+ return NPERR_FILE_NOT_FOUND;
+
+ //buffer.resize();
+
+ int bytesRead = fread(buffer.data(), 1, 0, fileHandle);
+
+ fclose(fileHandle);
+
+ if (bytesRead <= 0)
+ return NPERR_FILE_NOT_FOUND;
+
+ return NPERR_NO_ERROR;
+}
+
+NPError PluginView::getValueStatic(NPNVariable variable, void* value)
+{
+ switch (variable) {
+ case NPNVToolkit:
+#if PLATFORM(GTK)
+ *((uint32 *)value) = 2;
+#else
+ *((uint32 *)value) = 0;
+#endif
+ return NPERR_NO_ERROR;
+
+ case NPNVSupportsXEmbedBool:
+#if PLATFORM(X11)
+ *((uint32 *)value) = true;
+#else
+ *((uint32 *)value) = false;
+#endif
+ return NPERR_NO_ERROR;
+
+ case NPNVjavascriptEnabledBool:
+ *((uint32 *)value) = true;
+ return NPERR_NO_ERROR;
+
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+}
+
+NPError PluginView::getValue(NPNVariable variable, void* value)
+{
+ switch (variable) {
+ case NPNVxDisplay:
+#if PLATFORM(X11)
+ if (m_needsXEmbed)
+ *(void **)value = (void *)GDK_DISPLAY();
+ else
+ *(void **)value = (void *)GTK_XTBIN(platformPluginWidget())->xtclient.xtdisplay;
+ return NPERR_NO_ERROR;
+#else
+ return NPERR_GENERIC_ERROR;
+#endif
+
+#if PLATFORM(X11)
+ case NPNVxtAppContext:
+ if (!m_needsXEmbed) {
+ *(void **)value = XtDisplayToApplicationContext (GTK_XTBIN(platformPluginWidget())->xtclient.xtdisplay);
+
+ return NPERR_NO_ERROR;
+ } else
+ return NPERR_GENERIC_ERROR;
+#endif
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ case NPNVWindowNPObject: {
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
+ NPObject* windowScriptObject = m_parentFrame->script()->windowScriptNPObject();
+
+ // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html>
+ if (windowScriptObject)
+ _NPN_RetainObject(windowScriptObject);
+
+ void** v = (void**)value;
+ *v = windowScriptObject;
+
+ return NPERR_NO_ERROR;
+ }
+
+ case NPNVPluginElementNPObject: {
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
+ NPObject* pluginScriptObject = 0;
+
+ if (m_element->hasTagName(appletTag) || m_element->hasTagName(embedTag) || m_element->hasTagName(objectTag))
+ pluginScriptObject = static_cast<HTMLPlugInElement*>(m_element)->getNPObject();
+
+ // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html>
+ if (pluginScriptObject)
+ _NPN_RetainObject(pluginScriptObject);
+
+ void** v = (void**)value;
+ *v = pluginScriptObject;
+
+ return NPERR_NO_ERROR;
+ }
+#endif
+
+ case NPNVnetscapeWindow: {
+#if PLATFORM(X11)
+ void* w = reinterpret_cast<void*>(value);
+ *((XID *)w) = GDK_WINDOW_XWINDOW(m_parentFrame->view()->hostWindow()->platformWindow()->window);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ HGDIOBJ* w = reinterpret_cast<HGDIOBJ*>(value);
+ *w = GDK_WINDOW_HWND(m_parentFrame->view()->hostWindow()->platformWindow()->window);
+#endif
+ return NPERR_NO_ERROR;
+ }
+
+ default:
+ return getValueStatic(variable, value);
+ }
+}
+
+void PluginView::invalidateRect(const IntRect& rect)
+{
+ if (m_isWindowed) {
+ gtk_widget_queue_draw_area(GTK_WIDGET(platformPluginWidget()), rect.x(), rect.y(), rect.width(), rect.height());
+ return;
+ }
+
+ invalidateWindowlessPluginRect(rect);
+}
+
+void PluginView::invalidateRect(NPRect* rect)
+{
+ if (!rect) {
+ invalidate();
+ return;
+ }
+
+ IntRect r(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
+ invalidateRect(r);
+}
+
+void PluginView::forceRedraw()
+{
+ if (m_isWindowed)
+ gtk_widget_queue_draw(platformPluginWidget());
+ else
+ gtk_widget_queue_draw(m_parentFrame->view()->hostWindow()->platformWindow());
+}
+
+PluginView::~PluginView()
+{
+ stop();
+
+ deleteAllValues(m_requests);
+
+ freeStringArray(m_paramNames, m_paramCount);
+ freeStringArray(m_paramValues, m_paramCount);
+
+ m_parentFrame->script()->cleanupScriptObjectsForPlugin(this);
+
+ if (m_plugin && !(m_plugin->quirks().contains(PluginQuirkDontUnloadPlugin)))
+ m_plugin->unload();
+}
+
+static gboolean
+plug_removed_cb(GtkSocket *socket, gpointer)
+{
+ return TRUE;
+}
+
+void PluginView::init()
+{
+ if (m_haveInitialized)
+ return;
+ m_haveInitialized = true;
+
+ if (!m_plugin) {
+ ASSERT(m_status == PluginStatusCanNotFindPlugin);
+ return;
+ }
+
+ if (!m_plugin->load()) {
+ m_plugin = 0;
+ m_status = PluginStatusCanNotLoadPlugin;
+ return;
+ }
+
+ if (!start()) {
+ m_status = PluginStatusCanNotLoadPlugin;
+ return;
+ }
+
+ if (m_plugin->pluginFuncs()->getvalue) {
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginNeedsXEmbed, &m_needsXEmbed);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+
+#if PLATFORM(X11)
+ if (m_needsXEmbed) {
+ setPlatformWidget(gtk_socket_new());
+ gtk_container_add(GTK_CONTAINER(m_parentFrame->view()->hostWindow()->platformWindow()), platformPluginWidget());
+ g_signal_connect(platformPluginWidget(), "plug_removed", G_CALLBACK(plug_removed_cb), NULL);
+ } else if (m_isWindowed)
+ setPlatformWidget(gtk_xtbin_new(m_parentFrame->view()->hostWindow()->platformWindow()->window, 0));
+#else
+ setPlatformWidget(gtk_socket_new());
+ gtk_container_add(GTK_CONTAINER(m_parentFrame->view()->hostWindow()->platformWindow()), platformPluginWidget());
+#endif
+ show();
+
+ if (m_isWindowed) {
+ m_npWindow.type = NPWindowTypeWindow;
+#if PLATFORM(X11)
+ NPSetWindowCallbackStruct *ws = new NPSetWindowCallbackStruct();
+
+ ws->type = 0;
+
+ if (m_needsXEmbed) {
+ gtk_widget_realize(platformPluginWidget());
+ m_npWindow.window = (void*)gtk_socket_get_id(GTK_SOCKET(platformPluginWidget()));
+ ws->display = GDK_WINDOW_XDISPLAY(platformPluginWidget()->window);
+ ws->visual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(GDK_DRAWABLE(platformPluginWidget()->window)));
+ ws->depth = gdk_drawable_get_visual(GDK_DRAWABLE(platformPluginWidget()->window))->depth;
+ ws->colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(GDK_DRAWABLE(platformPluginWidget()->window)));
+ } else {
+ m_npWindow.window = (void*)GTK_XTBIN(platformPluginWidget())->xtwindow;
+ ws->display = GTK_XTBIN(platformPluginWidget())->xtdisplay;
+ ws->visual = GTK_XTBIN(platformPluginWidget())->xtclient.xtvisual;
+ ws->depth = GTK_XTBIN(platformPluginWidget())->xtclient.xtdepth;
+ ws->colormap = GTK_XTBIN(platformPluginWidget())->xtclient.xtcolormap;
+ }
+ XFlush (ws->display);
+
+ m_npWindow.ws_info = ws;
+#elif defined(GDK_WINDOWING_WIN32)
+ m_npWindow.window = (void*)GDK_WINDOW_HWND(platformPluginWidget()->window);
+#endif
+ } else {
+ m_npWindow.type = NPWindowTypeDrawable;
+ m_npWindow.window = 0;
+ }
+
+ if (!(m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)))
+ setNPWindowRect(frameRect());
+
+ m_status = PluginStatusLoadedSuccessfully;
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/gtk/gtk2xtbin.c b/WebCore/plugins/gtk/gtk2xtbin.c
new file mode 100644
index 0000000..4247345
--- /dev/null
+++ b/WebCore/plugins/gtk/gtk2xtbin.c
@@ -0,0 +1,946 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim:expandtab:shiftwidth=2:tabstop=2: */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Gtk2XtBin Widget Implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * The GtkXtBin widget allows for Xt toolkit code to be used
+ * inside a GTK application.
+ */
+
+#undef GTK_DISABLE_DEPRECATED
+
+#include "xembed.h"
+#include "gtk2xtbin.h"
+#include <gtk/gtkmain.h>
+#include <gtk/gtkprivate.h>
+#include <gdk/gdkx.h>
+#include <glib.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Xlib/Xt stuff */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Shell.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+/* uncomment this if you want debugging information about widget
+ creation and destruction */
+#undef DEBUG_XTBIN
+
+#define XTBIN_MAX_EVENTS 30
+
+static void gtk_xtbin_class_init (GtkXtBinClass *klass);
+static void gtk_xtbin_init (GtkXtBin *xtbin);
+static void gtk_xtbin_realize (GtkWidget *widget);
+static void gtk_xtbin_unrealize (GtkWidget *widget);
+static void gtk_xtbin_destroy (GtkObject *object);
+static void gtk_xtbin_shutdown (GtkObject *object);
+
+/* Xt aware XEmbed */
+static void xt_client_init (XtClient * xtclient,
+ Visual *xtvisual,
+ Colormap xtcolormap,
+ int xtdepth);
+static void xt_client_create (XtClient * xtclient,
+ Window embeder,
+ int height,
+ int width );
+static void xt_client_unrealize (XtClient* xtclient);
+static void xt_client_destroy (XtClient* xtclient);
+static void xt_client_set_info (Widget xtplug,
+ unsigned long flags);
+static void xt_client_event_handler (Widget w,
+ XtPointer client_data,
+ XEvent *event);
+static void xt_client_handle_xembed_message (Widget w,
+ XtPointer client_data,
+ XEvent *event);
+static void xt_client_focus_listener (Widget w,
+ XtPointer user_data,
+ XEvent *event);
+static void xt_add_focus_listener( Widget w, XtPointer user_data );
+static void xt_add_focus_listener_tree ( Widget treeroot, XtPointer user_data);
+static void xt_remove_focus_listener(Widget w, XtPointer user_data);
+static void send_xembed_message (XtClient *xtclient,
+ long message,
+ long detail,
+ long data1,
+ long data2,
+ long time);
+static int error_handler (Display *display,
+ XErrorEvent *error);
+/* For error trap of XEmbed */
+static void trap_errors(void);
+static int untrap_error(void);
+static int (*old_error_handler) (Display *, XErrorEvent *);
+static int trapped_error_code = 0;
+
+static GtkWidgetClass *parent_class = NULL;
+
+static Display *xtdisplay = NULL;
+static String *fallback = NULL;
+static gboolean xt_is_initialized = FALSE;
+static gint num_widgets = 0;
+
+static GPollFD xt_event_poll_fd;
+static gint xt_polling_timer_id = 0;
+static guint tag = 0;
+
+static gboolean
+xt_event_prepare (GSource* source_data,
+ gint *timeout)
+{
+ int mask;
+
+ GDK_THREADS_ENTER();
+ mask = XPending(xtdisplay);
+ GDK_THREADS_LEAVE();
+
+ return (gboolean)mask;
+}
+
+static gboolean
+xt_event_check (GSource* source_data)
+{
+ GDK_THREADS_ENTER ();
+
+ if (xt_event_poll_fd.revents & G_IO_IN) {
+ int mask;
+ mask = XPending(xtdisplay);
+ GDK_THREADS_LEAVE ();
+ return (gboolean)mask;
+ }
+
+ GDK_THREADS_LEAVE ();
+ return FALSE;
+}
+
+static gboolean
+xt_event_dispatch (GSource* source_data,
+ GSourceFunc call_back,
+ gpointer user_data)
+{
+ XEvent event;
+ XtAppContext ac;
+ int i = 0;
+
+ ac = XtDisplayToApplicationContext(xtdisplay);
+
+ GDK_THREADS_ENTER ();
+
+ /* Process only real X traffic here. We only look for data on the
+ * pipe, limit it to XTBIN_MAX_EVENTS and only call
+ * XtAppProcessEvent so that it will look for X events. There's no
+ * timer processing here since we already have a timer callback that
+ * does it. */
+ for (i=0; i < XTBIN_MAX_EVENTS && XPending(xtdisplay); i++) {
+ XtAppProcessEvent(ac, XtIMXEvent);
+ }
+
+ GDK_THREADS_LEAVE ();
+
+ return TRUE;
+}
+
+static GSourceFuncs xt_event_funcs = {
+ xt_event_prepare,
+ xt_event_check,
+ xt_event_dispatch,
+ g_free,
+ (GSourceFunc)NULL,
+ (GSourceDummyMarshal)NULL
+};
+
+static gboolean
+xt_event_polling_timer_callback(gpointer user_data)
+{
+ Display * display;
+ XtAppContext ac;
+ int eventsToProcess = 20;
+
+ display = (Display *)user_data;
+ ac = XtDisplayToApplicationContext(display);
+
+ /* We need to process many Xt events here. If we just process
+ one event we might starve one or more Xt consumers. On the other hand
+ this could hang the whole app if Xt events come pouring in. So process
+ up to 20 Xt events right now and save the rest for later. This is a hack,
+ but it oughta work. We *really* should have out of process plugins.
+ */
+ while (eventsToProcess-- && XtAppPending(ac))
+ XtAppProcessEvent(ac, XtIMAll);
+ return TRUE;
+}
+
+GType
+gtk_xtbin_get_type (void)
+{
+ static GType xtbin_type = 0;
+
+ if (!xtbin_type) {
+ static const GTypeInfo xtbin_info =
+ {
+ sizeof (GtkXtBinClass),
+ NULL,
+ NULL,
+
+ (GClassInitFunc)gtk_xtbin_class_init,
+ NULL,
+ NULL,
+
+ sizeof (GtkXtBin),
+ 0,
+ (GInstanceInitFunc)gtk_xtbin_init,
+ };
+ xtbin_type = g_type_register_static (GTK_TYPE_SOCKET,
+ "GtkXtBin",
+ &xtbin_info,
+ 0);
+ }
+ return xtbin_type;
+}
+
+static void
+gtk_xtbin_class_init (GtkXtBinClass *klass)
+{
+ GtkWidgetClass *widget_class;
+ GtkObjectClass *object_class;
+
+ parent_class = gtk_type_class (GTK_TYPE_SOCKET);
+
+ widget_class = GTK_WIDGET_CLASS (klass);
+ widget_class->realize = gtk_xtbin_realize;
+ widget_class->unrealize = gtk_xtbin_unrealize;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ object_class->destroy = gtk_xtbin_destroy;
+}
+
+static void
+gtk_xtbin_init (GtkXtBin *xtbin)
+{
+ xtbin->xtdisplay = NULL;
+ xtbin->parent_window = NULL;
+ xtbin->xtwindow = 0;
+ xtbin->x = 0;
+ xtbin->y = 0;
+}
+
+static void
+gtk_xtbin_realize (GtkWidget *widget)
+{
+ GtkXtBin *xtbin;
+ GtkAllocation allocation = { 0, 0, 200, 200 };
+ gint x, y, w, h, d; /* geometry of window */
+
+#ifdef DEBUG_XTBIN
+ printf("gtk_xtbin_realize()\n");
+#endif
+
+ g_return_if_fail (GTK_IS_XTBIN (widget));
+
+ xtbin = GTK_XTBIN (widget);
+
+ /* caculate the allocation before realize */
+ gdk_window_get_geometry(xtbin->parent_window, &x, &y, &w, &h, &d);
+ allocation.width = w;
+ allocation.height = h;
+ gtk_widget_size_allocate (widget, &allocation);
+
+#ifdef DEBUG_XTBIN
+ printf("initial allocation %d %d %d %d\n", x, y, w, h);
+#endif
+
+ xtbin->width = widget->allocation.width;
+ xtbin->height = widget->allocation.height;
+
+ /* use GtkSocket's realize */
+ (*GTK_WIDGET_CLASS(parent_class)->realize)(widget);
+
+ /* create the Xt client widget */
+ xt_client_create(&(xtbin->xtclient),
+ gtk_socket_get_id(GTK_SOCKET(xtbin)),
+ xtbin->height,
+ xtbin->width);
+ xtbin->xtwindow = XtWindow(xtbin->xtclient.child_widget);
+
+ gdk_flush();
+
+ /* now that we have created the xt client, add it to the socket. */
+ gtk_socket_add_id(GTK_SOCKET(widget), xtbin->xtwindow);
+}
+
+
+
+GtkWidget*
+gtk_xtbin_new (GdkWindow *parent_window, String * f)
+{
+ GtkXtBin *xtbin;
+ gpointer user_data;
+
+ assert(parent_window != NULL);
+ xtbin = gtk_type_new (GTK_TYPE_XTBIN);
+
+ if (!xtbin)
+ return (GtkWidget*)NULL;
+
+ if (f)
+ fallback = f;
+
+ /* Initialize the Xt toolkit */
+ xtbin->parent_window = parent_window;
+
+ xt_client_init(&(xtbin->xtclient),
+ GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()),
+ GDK_COLORMAP_XCOLORMAP(gdk_rgb_get_colormap()),
+ gdk_rgb_get_visual()->depth);
+
+ if (!xtbin->xtclient.xtdisplay) {
+ /* If XtOpenDisplay failed, we can't go any further.
+ * Bail out.
+ */
+#ifdef DEBUG_XTBIN
+ printf("gtk_xtbin_init: XtOpenDisplay() returned NULL.\n");
+#endif
+ g_free (xtbin);
+ return (GtkWidget *)NULL;
+ }
+
+ /* If this is the first running widget, hook this display into the
+ mainloop */
+ if (0 == num_widgets) {
+ int cnumber;
+ /*
+ * hook Xt event loop into the glib event loop.
+ */
+
+ /* the assumption is that gtk_init has already been called */
+ GSource* gs = g_source_new(&xt_event_funcs, sizeof(GSource));
+ if (!gs) {
+ return NULL;
+ }
+
+ g_source_set_priority(gs, GDK_PRIORITY_EVENTS);
+ g_source_set_can_recurse(gs, TRUE);
+ tag = g_source_attach(gs, (GMainContext*)NULL);
+#ifdef VMS
+ cnumber = XConnectionNumber(xtdisplay);
+#else
+ cnumber = ConnectionNumber(xtdisplay);
+#endif
+ xt_event_poll_fd.fd = cnumber;
+ xt_event_poll_fd.events = G_IO_IN;
+ xt_event_poll_fd.revents = 0; /* hmm... is this correct? */
+
+ g_main_context_add_poll ((GMainContext*)NULL,
+ &xt_event_poll_fd,
+ G_PRIORITY_LOW);
+ /* add a timer so that we can poll and process Xt timers */
+ xt_polling_timer_id =
+ gtk_timeout_add(25,
+ (GtkFunction)xt_event_polling_timer_callback,
+ xtdisplay);
+ }
+
+ /* Bump up our usage count */
+ num_widgets++;
+
+ /* Build the hierachy */
+ xtbin->xtdisplay = xtbin->xtclient.xtdisplay;
+ gtk_widget_set_parent_window(GTK_WIDGET(xtbin), parent_window);
+ gdk_window_get_user_data(xtbin->parent_window, &user_data);
+ if (user_data)
+ gtk_container_add(GTK_CONTAINER(user_data), GTK_WIDGET(xtbin));
+
+ return GTK_WIDGET (xtbin);
+}
+
+void
+gtk_xtbin_set_position (GtkXtBin *xtbin,
+ gint x,
+ gint y)
+{
+ xtbin->x = x;
+ xtbin->y = y;
+
+ if (GTK_WIDGET_REALIZED (xtbin))
+ gdk_window_move (GTK_WIDGET (xtbin)->window, x, y);
+}
+
+void
+gtk_xtbin_resize (GtkWidget *widget,
+ gint width,
+ gint height)
+{
+ Arg args[2];
+ GtkXtBin *xtbin = GTK_XTBIN (widget);
+ GtkAllocation allocation;
+
+#ifdef DEBUG_XTBIN
+ printf("gtk_xtbin_resize %p %d %d\n", (void *)widget, width, height);
+#endif
+
+ xtbin->height = height;
+ xtbin->width = width;
+
+ // Avoid BadValue errors in XtSetValues
+ if (height <= 0 || width <=0) {
+ height = 1;
+ width = 1;
+ }
+ XtSetArg(args[0], XtNheight, height);
+ XtSetArg(args[1], XtNwidth, width);
+ XtSetValues(xtbin->xtclient.top_widget, args, 2);
+
+ /* we need to send a size allocate so the socket knows about the
+ size changes */
+ allocation.x = xtbin->x;
+ allocation.y = xtbin->y;
+ allocation.width = xtbin->width;
+ allocation.height = xtbin->height;
+
+ gtk_widget_size_allocate(widget, &allocation);
+}
+
+static void
+gtk_xtbin_unrealize (GtkWidget *object)
+{
+ GtkXtBin *xtbin;
+ GtkWidget *widget;
+
+#ifdef DEBUG_XTBIN
+ printf("gtk_xtbin_unrealize()\n");
+#endif
+
+ /* gtk_object_destroy() will already hold a refcount on object
+ */
+ xtbin = GTK_XTBIN(object);
+ widget = GTK_WIDGET(object);
+
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
+ if (GTK_WIDGET_REALIZED (widget)) {
+ xt_client_unrealize(&(xtbin->xtclient));
+ }
+
+ (*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget);
+}
+
+static void
+gtk_xtbin_destroy (GtkObject *object)
+{
+ GtkXtBin *xtbin;
+
+#ifdef DEBUG_XTBIN
+ printf("gtk_xtbin_destroy()\n");
+#endif
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GTK_IS_XTBIN (object));
+
+ xtbin = GTK_XTBIN (object);
+
+ if(xtbin->xtwindow) {
+ /* remove the event handler */
+ xt_client_destroy(&(xtbin->xtclient));
+ xtbin->xtwindow = 0;
+
+ num_widgets--; /* reduce our usage count */
+
+ /* If this is the last running widget, remove the Xt display
+ connection from the mainloop */
+ if (0 == num_widgets) {
+#ifdef DEBUG_XTBIN
+ printf("removing the Xt connection from the main loop\n");
+#endif
+ g_main_context_remove_poll((GMainContext*)NULL, &xt_event_poll_fd);
+ g_source_remove(tag);
+
+ gtk_timeout_remove(xt_polling_timer_id);
+ xt_polling_timer_id = 0;
+ }
+ }
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(object);
+}
+
+/*
+* Following is the implementation of Xt XEmbedded for client side
+*/
+
+/* Initial Xt plugin */
+static void
+xt_client_init( XtClient * xtclient,
+ Visual *xtvisual,
+ Colormap xtcolormap,
+ int xtdepth)
+{
+ XtAppContext app_context;
+ char *mArgv[1];
+ int mArgc = 0;
+
+ /*
+ * Initialize Xt stuff
+ */
+ xtclient->top_widget = NULL;
+ xtclient->child_widget = NULL;
+ xtclient->xtdisplay = NULL;
+ xtclient->xtvisual = NULL;
+ xtclient->xtcolormap = 0;
+ xtclient->xtdepth = 0;
+
+ if (!xt_is_initialized) {
+#ifdef DEBUG_XTBIN
+ printf("starting up Xt stuff\n");
+#endif
+ XtToolkitInitialize();
+ app_context = XtCreateApplicationContext();
+ if (fallback)
+ XtAppSetFallbackResources(app_context, fallback);
+
+ xtdisplay = XtOpenDisplay(app_context, gdk_get_display(), NULL,
+ "Wrapper", NULL, 0, &mArgc, mArgv);
+ if (xtdisplay)
+ xt_is_initialized = TRUE;
+ }
+ xtclient->xtdisplay = xtdisplay;
+ xtclient->xtvisual = xtvisual;
+ xtclient->xtcolormap = xtcolormap;
+ xtclient->xtdepth = xtdepth;
+}
+
+/* Create the Xt client widgets
+* */
+static void
+xt_client_create ( XtClient* xtclient ,
+ Window embedderid,
+ int height,
+ int width )
+{
+ int n;
+ Arg args[6];
+ Widget child_widget;
+ Widget top_widget;
+
+#ifdef DEBUG_XTBIN
+ printf("xt_client_create() \n");
+#endif
+ top_widget = XtAppCreateShell("drawingArea", "Wrapper",
+ applicationShellWidgetClass,
+ xtclient->xtdisplay,
+ NULL, 0);
+ xtclient->top_widget = top_widget;
+
+ /* set size of Xt window */
+ n = 0;
+ XtSetArg(args[n], XtNheight, height);n++;
+ XtSetArg(args[n], XtNwidth, width);n++;
+ XtSetValues(top_widget, args, n);
+
+ child_widget = XtVaCreateWidget("form",
+ compositeWidgetClass,
+ top_widget, NULL);
+
+ n = 0;
+ XtSetArg(args[n], XtNheight, height);n++;
+ XtSetArg(args[n], XtNwidth, width);n++;
+ XtSetArg(args[n], XtNvisual, xtclient->xtvisual ); n++;
+ XtSetArg(args[n], XtNdepth, xtclient->xtdepth ); n++;
+ XtSetArg(args[n], XtNcolormap, xtclient->xtcolormap ); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetValues(child_widget, args, n);
+
+ XSync(xtclient->xtdisplay, FALSE);
+ xtclient->oldwindow = top_widget->core.window;
+ top_widget->core.window = embedderid;
+
+ /* this little trick seems to finish initializing the widget */
+#if XlibSpecificationRelease >= 6
+ XtRegisterDrawable(xtclient->xtdisplay,
+ embedderid,
+ top_widget);
+#else
+ _XtRegisterWindow( embedderid,
+ top_widget);
+#endif
+ XtRealizeWidget(child_widget);
+
+ /* listen to all Xt events */
+ XSelectInput(xtclient->xtdisplay,
+ XtWindow(top_widget),
+ 0x0FFFFF);
+ xt_client_set_info (child_widget, 0);
+
+ XtManageChild(child_widget);
+ xtclient->child_widget = child_widget;
+
+ /* set the event handler */
+ XtAddEventHandler(child_widget,
+ 0x0FFFFF & ~ResizeRedirectMask,
+ TRUE,
+ (XtEventHandler)xt_client_event_handler, xtclient);
+ XtAddEventHandler(child_widget,
+ SubstructureNotifyMask | ButtonReleaseMask,
+ TRUE,
+ (XtEventHandler)xt_client_focus_listener,
+ xtclient);
+ XSync(xtclient->xtdisplay, FALSE);
+}
+
+static void
+xt_client_unrealize ( XtClient* xtclient )
+{
+#if XlibSpecificationRelease >= 6
+ XtUnregisterDrawable(xtclient->xtdisplay,
+ xtclient->top_widget->core.window);
+#else
+ _XtUnregisterWindow(xtclient->top_widget->core.window,
+ xtclient->top_widget);
+#endif
+
+ /* flush the queue before we returning origin top_widget->core.window
+ or we can get X error since the window is gone */
+ XSync(xtclient->xtdisplay, False);
+
+ xtclient->top_widget->core.window = xtclient->oldwindow;
+ XtUnrealizeWidget(xtclient->top_widget);
+}
+
+static void
+xt_client_destroy (XtClient* xtclient)
+{
+ if(xtclient->top_widget) {
+ XtRemoveEventHandler(xtclient->child_widget, 0x0FFFFF, TRUE,
+ (XtEventHandler)xt_client_event_handler, xtclient);
+ XtDestroyWidget(xtclient->top_widget);
+ xtclient->top_widget = NULL;
+ }
+}
+
+static void
+xt_client_set_info (Widget xtplug, unsigned long flags)
+{
+ unsigned long buffer[2];
+
+ Atom infoAtom = XInternAtom(XtDisplay(xtplug), "_XEMBED_INFO", False);
+
+ buffer[1] = 0; /* Protocol version */
+ buffer[1] = flags;
+
+ XChangeProperty (XtDisplay(xtplug), XtWindow(xtplug),
+ infoAtom, infoAtom, 32,
+ PropModeReplace,
+ (unsigned char *)buffer, 2);
+}
+
+static void
+xt_client_handle_xembed_message(Widget w, XtPointer client_data, XEvent *event)
+{
+ XtClient *xtplug = (XtClient*)client_data;
+ switch (event->xclient.data.l[1])
+ {
+ case XEMBED_EMBEDDED_NOTIFY:
+ break;
+ case XEMBED_WINDOW_ACTIVATE:
+#ifdef DEBUG_XTBIN
+ printf("Xt client get XEMBED_WINDOW_ACTIVATE\n");
+#endif
+ break;
+ case XEMBED_WINDOW_DEACTIVATE:
+#ifdef DEBUG_XTBIN
+ printf("Xt client get XEMBED_WINDOW_DEACTIVATE\n");
+#endif
+ break;
+ case XEMBED_MODALITY_ON:
+#ifdef DEBUG_XTBIN
+ printf("Xt client get XEMBED_MODALITY_ON\n");
+#endif
+ break;
+ case XEMBED_MODALITY_OFF:
+#ifdef DEBUG_XTBIN
+ printf("Xt client get XEMBED_MODALITY_OFF\n");
+#endif
+ break;
+ case XEMBED_FOCUS_IN:
+ case XEMBED_FOCUS_OUT:
+ {
+ XEvent xevent;
+ memset(&xevent, 0, sizeof(xevent));
+
+ if(event->xclient.data.l[1] == XEMBED_FOCUS_IN) {
+#ifdef DEBUG_XTBIN
+ printf("XTEMBED got focus in\n");
+#endif
+ xevent.xfocus.type = FocusIn;
+ }
+ else {
+#ifdef DEBUG_XTBIN
+ printf("XTEMBED got focus out\n");
+#endif
+ xevent.xfocus.type = FocusOut;
+ }
+
+ xevent.xfocus.window = XtWindow(xtplug->child_widget);
+ xevent.xfocus.display = XtDisplay(xtplug->child_widget);
+ XSendEvent(XtDisplay(xtplug->child_widget),
+ xevent.xfocus.window,
+ False, NoEventMask,
+ &xevent );
+ XSync( XtDisplay(xtplug->child_widget), False);
+ }
+ break;
+ default:
+ break;
+ } /* End of XEmbed Message */
+}
+
+static void
+xt_client_event_handler( Widget w, XtPointer client_data, XEvent *event)
+{
+ XtClient *xtplug = (XtClient*)client_data;
+
+ switch(event->type)
+ {
+ case ClientMessage:
+ /* Handle xembed message */
+ if (event->xclient.message_type==
+ XInternAtom (XtDisplay(xtplug->child_widget),
+ "_XEMBED", False)) {
+ xt_client_handle_xembed_message(w, client_data, event);
+ }
+ break;
+ case ReparentNotify:
+ break;
+ case MappingNotify:
+ xt_client_set_info (w, XEMBED_MAPPED);
+ break;
+ case UnmapNotify:
+ xt_client_set_info (w, 0);
+ break;
+ case FocusIn:
+ send_xembed_message ( xtplug,
+ XEMBED_REQUEST_FOCUS, 0, 0, 0, 0);
+ break;
+ case FocusOut:
+ break;
+ case KeyPress:
+#ifdef DEBUG_XTBIN
+ printf("Key Press Got!\n");
+#endif
+ break;
+ default:
+ break;
+ } /* End of switch(event->type) */
+}
+
+static void
+send_xembed_message (XtClient *xtclient,
+ long message,
+ long detail,
+ long data1,
+ long data2,
+ long time)
+{
+ XEvent xevent;
+ Window w=XtWindow(xtclient->top_widget);
+ Display* dpy=xtclient->xtdisplay;
+ int errorcode;
+
+ memset(&xevent,0,sizeof(xevent));
+ xevent.xclient.window = w;
+ xevent.xclient.type = ClientMessage;
+ xevent.xclient.message_type = XInternAtom(dpy,"_XEMBED",False);
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = time;
+ xevent.xclient.data.l[1] = message;
+ xevent.xclient.data.l[2] = detail;
+ xevent.xclient.data.l[3] = data1;
+ xevent.xclient.data.l[4] = data2;
+
+ trap_errors ();
+ XSendEvent (dpy, w, False, NoEventMask, &xevent);
+ XSync (dpy,False);
+
+ if((errorcode = untrap_error())) {
+#ifdef DEBUG_XTBIN
+ printf("send_xembed_message error(%d)!!!\n",errorcode);
+#endif
+ }
+}
+
+static int
+error_handler(Display *display, XErrorEvent *error)
+{
+ trapped_error_code = error->error_code;
+ return 0;
+}
+
+static void
+trap_errors(void)
+{
+ trapped_error_code =0;
+ old_error_handler = XSetErrorHandler(error_handler);
+}
+
+static int
+untrap_error(void)
+{
+ XSetErrorHandler(old_error_handler);
+ if(trapped_error_code) {
+#ifdef DEBUG_XTBIN
+ printf("Get X Window Error = %d\n", trapped_error_code);
+#endif
+ }
+ return trapped_error_code;
+}
+
+static void
+xt_client_focus_listener( Widget w, XtPointer user_data, XEvent *event)
+{
+ Display *dpy = XtDisplay(w);
+ XtClient *xtclient = user_data;
+ Window win = XtWindow(w);
+
+ switch(event->type)
+ {
+ case CreateNotify:
+ if(event->xcreatewindow.parent == win) {
+ Widget child=XtWindowToWidget( dpy, event->xcreatewindow.window);
+ if (child)
+ xt_add_focus_listener_tree(child, user_data);
+ }
+ break;
+ case DestroyNotify:
+ xt_remove_focus_listener( w, user_data);
+ break;
+ case ReparentNotify:
+ if(event->xreparent.parent == win) {
+ /* I am the new parent */
+ Widget child=XtWindowToWidget(dpy, event->xreparent.window);
+ if (child)
+ xt_add_focus_listener_tree( child, user_data);
+ }
+ else if(event->xreparent.window == win) {
+ /* I am the new child */
+ }
+ else {
+ /* I am the old parent */
+ }
+ break;
+ case ButtonRelease:
+#if 0
+ XSetInputFocus(dpy, XtWindow(xtclient->child_widget), RevertToParent, event->xbutton.time);
+#endif
+ send_xembed_message ( xtclient,
+ XEMBED_REQUEST_FOCUS, 0, 0, 0, 0);
+ break;
+ default:
+ break;
+ } /* End of switch(event->type) */
+}
+
+static void
+xt_add_focus_listener( Widget w, XtPointer user_data)
+{
+ XWindowAttributes attr;
+ long eventmask;
+ XtClient *xtclient = user_data;
+ int errorcode;
+
+ trap_errors ();
+ XGetWindowAttributes(XtDisplay(w), XtWindow(w), &attr);
+ eventmask = attr.your_event_mask | SubstructureNotifyMask | ButtonReleaseMask;
+ XSelectInput(XtDisplay(w),
+ XtWindow(w),
+ eventmask);
+
+ XtAddEventHandler(w,
+ SubstructureNotifyMask | ButtonReleaseMask,
+ TRUE,
+ (XtEventHandler)xt_client_focus_listener,
+ xtclient);
+ untrap_error();
+}
+
+static void
+xt_remove_focus_listener(Widget w, XtPointer user_data)
+{
+ int errorcode;
+
+ trap_errors ();
+ XtRemoveEventHandler(w, SubstructureNotifyMask | ButtonReleaseMask, TRUE,
+ (XtEventHandler)xt_client_focus_listener, user_data);
+
+ untrap_error();
+}
+
+static void
+xt_add_focus_listener_tree ( Widget treeroot, XtPointer user_data)
+{
+ Window win = XtWindow(treeroot);
+ Window *children;
+ Window root, parent;
+ Display *dpy = XtDisplay(treeroot);
+ unsigned int i, nchildren;
+
+ /* ensure we don't add more than once */
+ xt_remove_focus_listener( treeroot, user_data);
+ xt_add_focus_listener( treeroot, user_data);
+ trap_errors();
+ if(!XQueryTree(dpy, win, &root, &parent, &children, &nchildren)) {
+ untrap_error();
+ return;
+ }
+
+ if(untrap_error())
+ return;
+
+ for(i=0; i<nchildren; ++i) {
+ Widget child = XtWindowToWidget(dpy, children[i]);
+ if (child)
+ xt_add_focus_listener_tree( child, user_data);
+ }
+ XFree((void*)children);
+
+ return;
+}
diff --git a/WebCore/plugins/gtk/gtk2xtbin.h b/WebCore/plugins/gtk/gtk2xtbin.h
new file mode 100644
index 0000000..2a2b92c
--- /dev/null
+++ b/WebCore/plugins/gtk/gtk2xtbin.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set expandtab shiftwidth=2 tabstop=2: */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Gtk2XtBin Widget Implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __GTK_XTBIN_H__
+#define __GTK_XTBIN_H__
+
+#include <gtk/gtksocket.h>
+#include <X11/Intrinsic.h>
+#include <X11/Xutil.h>
+#include <X11/Xlib.h>
+#ifdef MOZILLA_CLIENT
+#include "nscore.h"
+#ifdef _IMPL_GTKXTBIN_API
+#define GTKXTBIN_API(type) NS_EXPORT_(type)
+#else
+#define GTKXTBIN_API(type) NS_IMPORT_(type)
+#endif
+#else
+#define GTKXTBIN_API(type) type
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GtkXtBin GtkXtBin;
+typedef struct _GtkXtBinClass GtkXtBinClass;
+
+#define GTK_TYPE_XTBIN (gtk_xtbin_get_type ())
+#define GTK_XTBIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GTK_TYPE_XTBIN, GtkXtBin))
+#define GTK_XTBIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GTK_TYPE_XTBIN, GtkXtBinClass))
+#define GTK_IS_XTBIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GTK_TYPE_XTBIN))
+#define GTK_IS_XTBIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GTK_TYPE_XTBIN))
+typedef struct _XtClient XtClient;
+
+struct _XtClient {
+ Display *xtdisplay;
+ Widget top_widget; /* The toplevel widget */
+ Widget child_widget; /* The embedded widget */
+ Visual *xtvisual;
+ int xtdepth;
+ Colormap xtcolormap;
+ Window oldwindow;
+};
+
+struct _GtkXtBin
+{
+ GtkSocket gsocket;
+ GdkWindow *parent_window;
+ Display *xtdisplay; /* Xt Toolkit Display */
+
+ Window xtwindow; /* Xt Toolkit XWindow */
+ gint x, y;
+ gint width, height;
+ XtClient xtclient; /* Xt Client for XEmbed */
+};
+
+struct _GtkXtBinClass
+{
+ GtkSocketClass widget_class;
+};
+
+GTKXTBIN_API(GType) gtk_xtbin_get_type (void);
+GTKXTBIN_API(GtkWidget *) gtk_xtbin_new (GdkWindow *parent_window, String *f);
+GTKXTBIN_API(void) gtk_xtbin_set_position (GtkXtBin *xtbin,
+ gint x,
+ gint y);
+GTKXTBIN_API(void) gtk_xtbin_resize (GtkWidget *widget,
+ gint width,
+ gint height);
+
+typedef struct _XtTMRec {
+ XtTranslations translations; /* private to Translation Manager */
+ XtBoundActions proc_table; /* procedure bindings for actions */
+ struct _XtStateRec *current_state; /* Translation Manager state ptr */
+ unsigned long lastEventTime;
+} XtTMRec, *XtTM;
+
+typedef struct _CorePart {
+ Widget self; /* pointer to widget itself */
+ WidgetClass widget_class; /* pointer to Widget's ClassRec */
+ Widget parent; /* parent widget */
+ XrmName xrm_name; /* widget resource name quarkified */
+ Boolean being_destroyed; /* marked for destroy */
+ XtCallbackList destroy_callbacks; /* who to call when widget destroyed */
+ XtPointer constraints; /* constraint record */
+ Position x, y; /* window position */
+ Dimension width, height; /* window dimensions */
+ Dimension border_width; /* window border width */
+ Boolean managed; /* is widget geometry managed? */
+ Boolean sensitive; /* is widget sensitive to user events*/
+ Boolean ancestor_sensitive; /* are all ancestors sensitive? */
+ XtEventTable event_table; /* private to event dispatcher */
+ XtTMRec tm; /* translation management */
+ XtTranslations accelerators; /* accelerator translations */
+ Pixel border_pixel; /* window border pixel */
+ Pixmap border_pixmap; /* window border pixmap or NULL */
+ WidgetList popup_list; /* list of popups */
+ Cardinal num_popups; /* how many popups */
+ String name; /* widget resource name */
+ Screen *screen; /* window's screen */
+ Colormap colormap; /* colormap */
+ Window window; /* window ID */
+ Cardinal depth; /* number of planes in window */
+ Pixel background_pixel; /* window background pixel */
+ Pixmap background_pixmap; /* window background pixmap or NULL */
+ Boolean visible; /* is window mapped and not occluded?*/
+ Boolean mapped_when_managed;/* map window if it's managed? */
+} CorePart;
+
+typedef struct _WidgetRec {
+ CorePart core;
+ } WidgetRec, CoreRec;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __GTK_XTBIN_H__ */
diff --git a/WebCore/plugins/gtk/xembed.h b/WebCore/plugins/gtk/xembed.h
new file mode 100644
index 0000000..dff7be9
--- /dev/null
+++ b/WebCore/plugins/gtk/xembed.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim:expandtab:shiftwidth=2:tabstop=2: */
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the XEMBED Declaration.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* XEMBED messages */
+#define XEMBED_EMBEDDED_NOTIFY 0
+#define XEMBED_WINDOW_ACTIVATE 1
+#define XEMBED_WINDOW_DEACTIVATE 2
+#define XEMBED_REQUEST_FOCUS 3
+#define XEMBED_FOCUS_IN 4
+#define XEMBED_FOCUS_OUT 5
+#define XEMBED_FOCUS_NEXT 6
+#define XEMBED_FOCUS_PREV 7
+#define XEMBED_GRAB_KEY 8
+#define XEMBED_UNGRAB_KEY 9
+#define XEMBED_MODALITY_ON 10
+#define XEMBED_MODALITY_OFF 11
+
+/* Non standard messages*/
+#define XEMBED_GTK_GRAB_KEY 108
+#define XEMBED_GTK_UNGRAB_KEY 109
+
+/* Details for XEMBED_FOCUS_IN: */
+#define XEMBED_FOCUS_CURRENT 0
+#define XEMBED_FOCUS_FIRST 1
+#define XEMBED_FOCUS_LAST 2
+
+/* Flags for _XEMBED_INFO */
+#define XEMBED_MAPPED (1 << 0)
diff --git a/WebCore/plugins/mac/PluginDataMac.mm b/WebCore/plugins/mac/PluginDataMac.mm
new file mode 100644
index 0000000..ec76c37
--- /dev/null
+++ b/WebCore/plugins/mac/PluginDataMac.mm
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "PluginData.h"
+
+#import "BlockExceptions.h"
+#import "Logging.h"
+#import "WebCoreViewFactory.h"
+
+namespace WebCore {
+
+void PluginData::initPlugins()
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+ NSArray* plugins = [[WebCoreViewFactory sharedFactory] pluginsInfo];
+ for (unsigned int i = 0; i < [plugins count]; ++i) {
+ PluginInfo* pluginInfo = new PluginInfo;
+
+ id <WebCorePluginInfo> plugin = [plugins objectAtIndex:i];
+
+ pluginInfo->name = [plugin name];
+ pluginInfo->file = [plugin filename];
+ pluginInfo->desc = [plugin pluginDescription];
+
+ NSEnumerator* MIMETypeEnumerator = [plugin MIMETypeEnumerator];
+ while (NSString* MIME = [MIMETypeEnumerator nextObject]) {
+ MimeClassInfo* mime = new MimeClassInfo;
+ pluginInfo->mimes.append(mime);
+ mime->type = String(MIME).lower();
+ mime->suffixes = [[plugin extensionsForMIMEType:MIME] componentsJoinedByString:@","];
+ mime->desc = [plugin descriptionForMIMEType:MIME];
+ mime->plugin = pluginInfo;
+ }
+
+ m_plugins.append(pluginInfo);
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS;
+
+ return;
+}
+
+void PluginData::refresh()
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ [[WebCoreViewFactory sharedFactory] refreshPlugins];
+ END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+}
+
diff --git a/WebCore/plugins/npapi.cpp b/WebCore/plugins/npapi.cpp
index 2f44ba7..05d7c06 100644
--- a/WebCore/plugins/npapi.cpp
+++ b/WebCore/plugins/npapi.cpp
@@ -26,8 +26,9 @@
#include "config.h"
#include "PluginInfoStore.h"
+#include "PluginMainThreadScheduler.h"
#include "PluginView.h"
-#include "npapi.h" // #includes <windows.h>
+#include "npruntime_internal.h"
using namespace WebCore;
@@ -107,10 +108,8 @@ const char* NPN_UserAgent(NPP instance)
{
PluginView* view = pluginViewForInstance(instance);
- // FIXME: Some plug-ins call NPN_UserAgent with a null instance in their NP_initialize function!
- // We'd need a way to get a user agent without having a frame around.
if (!view)
- return 0;
+ return PluginView::userAgentStatic();
return view->userAgent();
}
@@ -137,6 +136,11 @@ void NPN_ForceRedraw(NPP instance)
NPError NPN_GetValue(NPP instance, NPNVariable variable, void* value)
{
+ PluginView* view = pluginViewForInstance(instance);
+
+ if (!view)
+ return PluginView::getValueStatic(variable, value);
+
return pluginViewForInstance(instance)->getValue(variable, value);
}
@@ -157,14 +161,33 @@ void* NPN_GetJavaPeer(NPP instance)
return 0;
}
-void
-NPN_PushPopupsEnabledState(NPP instance, NPBool enabled)
+void NPN_PushPopupsEnabledState(NPP instance, NPBool enabled)
{
pluginViewForInstance(instance)->pushPopupsEnabledState(enabled);
}
-void
-NPN_PopPopupsEnabledState(NPP instance)
+void NPN_PopPopupsEnabledState(NPP instance)
{
pluginViewForInstance(instance)->popPopupsEnabledState();
}
+
+void NPN_PluginThreadAsyncCall(NPP instance, void (*func) (void *), void *userData)
+{
+ PluginMainThreadScheduler::scheduler().scheduleCall(instance, func, userData);
+}
+
+#ifdef PLUGIN_SCHEDULE_TIMER
+uint32 NPN_ScheduleTimer(NPP instance, uint32 interval, NPBool repeat,
+ void (*timerFunc)(NPP npp, uint32 timerID))
+{
+ return pluginViewForInstance(instance)->scheduleTimer(instance, interval,
+ repeat != 0, timerFunc);
+}
+
+void NPN_UnscheduleTimer(NPP instance, uint32 timerID)
+{
+ pluginViewForInstance(instance)->unscheduleTimer(instance, timerID);
+}
+#endif
+
+
diff --git a/WebCore/plugins/npfunctions.h b/WebCore/plugins/npfunctions.h
index c847504..21e2e15 100644
--- a/WebCore/plugins/npfunctions.h
+++ b/WebCore/plugins/npfunctions.h
@@ -22,11 +22,15 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef NPFUNCTIONS_H
+#define NPFUNCTIONS_H
-#ifndef _NPFUNCTIONS_H_
-#define _NPFUNCTIONS_H_
-#include "npruntime_internal.h"
+#include "npruntime.h"
+#include "npapi.h"
+#if defined(ANDROID_PLUGINS)
+#include "nativehelper/jni.h"
+#endif
#ifdef __cplusplus
extern "C" {
@@ -59,8 +63,12 @@ typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* URL, const char*
typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* URL, const char* window, uint32 len, const char* buf, NPBool file);
typedef void* (*NPN_GetJavaEnvProcPtr)(void);
typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
-typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP instance, NPBool enabled);
-typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP instance);
+typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP instance, NPBool enabled);
+typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP instance);
+typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP npp, void (*func)(void *), void *userData);
+typedef uint32 (*NPN_ScheduleTimerProcPtr)(NPP npp, uint32 interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32 timerID));
+typedef void (*NPN_UnscheduleTimerProcPtr)(NPP npp, uint32 timerID);
+typedef NPError (*NPN_PopUpContextMenuProcPtr)(NPP instance, NPMenu* menu);
typedef void (*NPN_ReleaseVariantValueProcPtr) (NPVariant *variant);
@@ -84,6 +92,7 @@ typedef bool (*NPN_HasMethodProcPtr) (NPP npp, NPObject *npobj, NPIdentifier met
typedef bool (*NPN_RemovePropertyProcPtr) (NPP npp, NPObject *obj, NPIdentifier propertyName);
typedef void (*NPN_SetExceptionProcPtr) (NPObject *obj, const NPUTF8 *message);
typedef bool (*NPN_EnumerateProcPtr) (NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count);
+typedef bool (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
typedef NPError (*NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved);
typedef NPError (*NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
@@ -98,10 +107,9 @@ typedef int16 (*NPP_HandleEventProcPtr)(NPP instance, void* event);
typedef void (*NPP_URLNotifyProcPtr)(NPP instance, const char* URL, NPReason reason, void* notifyData);
typedef NPError (*NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value);
typedef NPError (*NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value);
-typedef EXPORTED_CALLBACK(void, NPP_ShutdownProcPtr)(void);
typedef void *(*NPP_GetJavaClassProcPtr)(void);
-typedef void* JRIGlobalRef; //not using this right now
+typedef void* JRIGlobalRef; //not using this right now
typedef struct _NPNetscapeFuncs {
uint16 size;
@@ -151,6 +159,11 @@ typedef struct _NPNetscapeFuncs {
NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate;
NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate;
NPN_EnumerateProcPtr enumerate;
+ NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
+ NPN_ConstructProcPtr construct;
+ NPN_ScheduleTimerProcPtr scheduletimer;
+ NPN_UnscheduleTimerProcPtr unscheduletimer;
+ NPN_PopUpContextMenuProcPtr popupcontextmenu;
} NPNetscapeFuncs;
typedef struct _NPPluginFuncs {
@@ -172,19 +185,22 @@ typedef struct _NPPluginFuncs {
NPP_SetValueProcPtr setvalue;
} NPPluginFuncs;
-#if defined(XP_WIN)
-typedef EXPORTED_CALLBACK(NPError, NP_InitializeFuncPtr)(NPNetscapeFuncs*);
typedef EXPORTED_CALLBACK(NPError, NP_GetEntryPointsFuncPtr)(NPPluginFuncs*);
-#endif
+typedef EXPORTED_CALLBACK(void, NPP_ShutdownProcPtr)(void);
#if defined(XP_MACOSX)
-typedef void (*BP_CreatePluginMIMETypesPreferencesFuncPtr)(void);
+typedef void (*BP_CreatePluginMIMETypesPreferencesFuncPtr)(void);
typedef NPError (*MainFuncPtr)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownProcPtr*);
#endif
#if defined(XP_UNIX)
typedef EXPORTED_CALLBACK(NPError, NP_InitializeFuncPtr)(NPNetscapeFuncs*, NPPluginFuncs*);
typedef EXPORTED_CALLBACK(char*, NP_GetMIMEDescriptionFuncPtr)(void);
+#elif defined(ANDROID_PLUGINS)
+typedef EXPORTED_CALLBACK(NPError, NP_InitializeFuncPtr)(NPNetscapeFuncs*, NPPluginFuncs*, JNIEnv *java_environment, jobject application_context);
+typedef EXPORTED_CALLBACK(char*, NP_GetMIMEDescriptionFuncPtr)(void);
+#else
+typedef EXPORTED_CALLBACK(NPError, NP_InitializeFuncPtr)(NPNetscapeFuncs*);
#endif
#ifdef __cplusplus
diff --git a/WebCore/plugins/qt/PluginDataQt.cpp b/WebCore/plugins/qt/PluginDataQt.cpp
new file mode 100644
index 0000000..13f1442
--- /dev/null
+++ b/WebCore/plugins/qt/PluginDataQt.cpp
@@ -0,0 +1,108 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2008 Collabora Ltd. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "PluginData.h"
+
+#include "PluginDatabase.h"
+#include "PluginPackage.h"
+
+#if QT_VERSION >= 0x040400
+#include "ChromeClientQt.h"
+#include "Page.h"
+#include <qwebpage.h>
+#include <qwebpluginfactory.h>
+#endif
+
+namespace WebCore {
+
+void PluginData::initPlugins()
+{
+#if QT_VERSION >= 0x040400
+ QWebPage* webPage = static_cast<ChromeClientQt*>(m_page->chrome()->client())->m_webPage;
+ QWebPluginFactory* factory = webPage->pluginFactory();
+ if (factory) {
+
+ QList<QWebPluginFactory::Plugin> qplugins = factory->plugins();
+ for (int i = 0; i < qplugins.count(); ++i) {
+ const QWebPluginFactory::Plugin& qplugin = qplugins.at(i);
+
+ PluginInfo* info = new PluginInfo;
+ info->name = qplugin.name;
+ info->desc = qplugin.description;
+
+ for (int j = 0; j < qplugin.mimeTypes.count(); ++j) {
+ const QWebPluginFactory::MimeType& mimeType = qplugin.mimeTypes.at(j);
+
+ MimeClassInfo* mimeInfo = new MimeClassInfo;
+ mimeInfo->type = mimeType.name;
+ mimeInfo->desc = mimeType.description;
+ mimeInfo->suffixes = mimeType.fileExtensions.join("; ");
+
+ info->mimes.append(mimeInfo);
+ }
+
+ m_plugins.append(info);
+ }
+ }
+#endif
+
+ PluginDatabase *db = PluginDatabase::installedPlugins();
+ const Vector<PluginPackage*> &plugins = db->plugins();
+
+ for (unsigned int i = 0; i < plugins.size(); ++i) {
+ PluginInfo* info = new PluginInfo;
+ PluginPackage* package = plugins[i];
+
+ info->name = package->name();
+ info->file = package->fileName();
+ info->desc = package->description();
+
+ const MIMEToDescriptionsMap& mimeToDescriptions = package->mimeToDescriptions();
+ MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end();
+ for (MIMEToDescriptionsMap::const_iterator it = mimeToDescriptions.begin(); it != end; ++it) {
+ MimeClassInfo* mime = new MimeClassInfo;
+ info->mimes.append(mime);
+
+ mime->type = it->first;
+ mime->desc = it->second;
+ mime->plugin = info;
+
+ Vector<String> extensions = package->mimeToExtensions().get(mime->type);
+
+ for (unsigned i = 0; i < extensions.size(); i++) {
+ if (i > 0)
+ mime->suffixes += ",";
+
+ mime->suffixes += extensions[i];
+ }
+ }
+
+ m_plugins.append(info);
+ }
+}
+
+void PluginData::refresh()
+{
+ PluginDatabase *db = PluginDatabase::installedPlugins();
+ db->refresh();
+}
+
+};
diff --git a/WebCore/plugins/qt/PluginPackageQt.cpp b/WebCore/plugins/qt/PluginPackageQt.cpp
new file mode 100644
index 0000000..423c4e1
--- /dev/null
+++ b/WebCore/plugins/qt/PluginPackageQt.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginPackage.h"
+
+#include "CString.h"
+#include "MIMETypeRegistry.h"
+#include "NotImplemented.h"
+#include "npruntime_impl.h"
+#include "PluginDatabase.h"
+#include "PluginDebug.h"
+
+namespace WebCore {
+
+void PluginPackage::determineQuirks(const String& mimeType)
+{
+ if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) {
+ // Because a single process cannot create multiple VMs, and we cannot reliably unload a
+ // Java VM, we cannot unload the Java plugin, or we'll lose reference to our only VM
+ m_quirks.add(PluginQuirkDontUnloadPlugin);
+
+ // Setting the window region to an empty region causes bad scrolling repaint problems
+ // with the Java plug-in.
+ m_quirks.add(PluginQuirkDontClipToZeroRectWhenScrolling);
+ }
+
+ if (mimeType == "application/x-shockwave-flash") {
+ // The flash plugin only requests windowless plugins if we return a mozilla user agent
+ m_quirks.add(PluginQuirkWantsMozillaUserAgent);
+ m_quirks.add(PluginQuirkThrottleInvalidate);
+ m_quirks.add(PluginQuirkThrottleWMUserPlusOneMessages);
+ m_quirks.add(PluginQuirkFlashURLNotifyBug);
+ }
+
+}
+
+bool PluginPackage::fetchInfo()
+{
+ if (!load())
+ return false;
+
+ NPP_GetValueProcPtr gv = (NPP_GetValueProcPtr)m_module->resolve("NP_GetValue");
+ typedef char *(*NPP_GetMIMEDescriptionProcPtr)();
+ NPP_GetMIMEDescriptionProcPtr gm =
+ (NPP_GetMIMEDescriptionProcPtr)m_module->resolve("NP_GetMIMEDescription");
+ if (!gm || !gv) {
+ return false;
+ }
+ char *buf = 0;
+ NPError err = gv(0, NPPVpluginNameString, (void *)&buf);
+ if (err != NPERR_NO_ERROR) {
+ return false;
+ }
+ m_name = buf;
+ err = gv(0, NPPVpluginDescriptionString, (void *)&buf);
+ if (err != NPERR_NO_ERROR) {
+ return false;
+ }
+ m_description = buf;
+
+ String s = gm();
+ Vector<String> types;
+ s.split(UChar(';'), false, types);
+ for (int i = 0; i < types.size(); ++i) {
+ Vector<String> mime;
+ types[i].split(UChar(':'), true, mime);
+ if (mime.size() > 0) {
+ Vector<String> exts;
+ if (mime.size() > 1)
+ mime[1].split(UChar(','), false, exts);
+ determineQuirks(mime[0]);
+ m_mimeToExtensions.add(mime[0], exts);
+ if (mime.size() > 2)
+ m_mimeToDescriptions.add(mime[0], mime[2]);
+ }
+ }
+
+ return true;
+}
+
+bool PluginPackage::load()
+{
+ if (m_isLoaded) {
+ m_loadCount++;
+ return true;
+ }
+
+ m_module = new QLibrary((QString)m_path);
+ m_module->setLoadHints(QLibrary::ResolveAllSymbolsHint);
+ if (!m_module->load()) {
+ LOG(Plugin, "%s not loaded", m_path.utf8().data());
+ return false;
+ }
+
+ m_isLoaded = true;
+
+ NP_InitializeFuncPtr NP_Initialize;
+ NPError npErr;
+
+ NP_Initialize = (NP_InitializeFuncPtr)m_module->resolve("NP_Initialize");
+ m_NPP_Shutdown = (NPP_ShutdownProcPtr)m_module->resolve("NP_Shutdown");
+
+ if (!NP_Initialize || !m_NPP_Shutdown)
+ goto abort;
+
+ memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs));
+ m_pluginFuncs.size = sizeof(m_pluginFuncs);
+
+ m_browserFuncs.size = sizeof (m_browserFuncs);
+ m_browserFuncs.version = NP_VERSION_MINOR;
+ m_browserFuncs.geturl = NPN_GetURL;
+ m_browserFuncs.posturl = NPN_PostURL;
+ m_browserFuncs.requestread = NPN_RequestRead;
+ m_browserFuncs.newstream = NPN_NewStream;
+ m_browserFuncs.write = NPN_Write;
+ m_browserFuncs.destroystream = NPN_DestroyStream;
+ m_browserFuncs.status = NPN_Status;
+ m_browserFuncs.uagent = NPN_UserAgent;
+ m_browserFuncs.memalloc = NPN_MemAlloc;
+ m_browserFuncs.memfree = NPN_MemFree;
+ m_browserFuncs.memflush = NPN_MemFlush;
+ m_browserFuncs.reloadplugins = NPN_ReloadPlugins;
+ m_browserFuncs.geturlnotify = NPN_GetURLNotify;
+ m_browserFuncs.posturlnotify = NPN_PostURLNotify;
+ m_browserFuncs.getvalue = NPN_GetValue;
+ m_browserFuncs.setvalue = NPN_SetValue;
+ m_browserFuncs.invalidaterect = NPN_InvalidateRect;
+ m_browserFuncs.invalidateregion = NPN_InvalidateRegion;
+ m_browserFuncs.forceredraw = NPN_ForceRedraw;
+ m_browserFuncs.getJavaEnv = NPN_GetJavaEnv;
+ m_browserFuncs.getJavaPeer = NPN_GetJavaPeer;
+ m_browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState;
+ m_browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState;
+
+ m_browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
+ m_browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
+ m_browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers;
+ m_browserFuncs.getintidentifier = _NPN_GetIntIdentifier;
+ m_browserFuncs.identifierisstring = _NPN_IdentifierIsString;
+ m_browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier;
+ m_browserFuncs.createobject = _NPN_CreateObject;
+ m_browserFuncs.retainobject = _NPN_RetainObject;
+ m_browserFuncs.releaseobject = _NPN_ReleaseObject;
+ m_browserFuncs.invoke = _NPN_Invoke;
+ m_browserFuncs.invokeDefault = _NPN_InvokeDefault;
+ m_browserFuncs.evaluate = _NPN_Evaluate;
+ m_browserFuncs.getproperty = _NPN_GetProperty;
+ m_browserFuncs.setproperty = _NPN_SetProperty;
+ m_browserFuncs.removeproperty = _NPN_RemoveProperty;
+ m_browserFuncs.hasproperty = _NPN_HasMethod;
+ m_browserFuncs.hasmethod = _NPN_HasProperty;
+ m_browserFuncs.setexception = _NPN_SetException;
+ m_browserFuncs.enumerate = _NPN_Enumerate;
+ m_browserFuncs.construct = _NPN_Construct;
+
+#if defined(XP_UNIX)
+ npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
+#else
+ npErr = NP_Initialize(&m_browserFuncs);
+#endif
+ if (npErr != NPERR_NO_ERROR)
+ goto abort;
+
+ m_loadCount++;
+ return true;
+
+abort:
+ unloadWithoutShutdown();
+ return false;
+}
+
+unsigned PluginPackage::hash() const
+{
+ unsigned hashCodes[2] = {
+ m_path.impl()->hash(),
+ m_lastModified
+ };
+
+ return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), 2 * sizeof(unsigned) / sizeof(UChar));
+}
+
+bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b)
+{
+ return a.m_description == b.m_description;
+}
+
+int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const
+{
+ // return -1, 0, or 1 if plug-in version is less than, equal to, or greater than
+ // the passed version
+ if (m_moduleVersion != compareVersion)
+ return m_moduleVersion > compareVersion ? 1 : -1;
+ return 0;
+}
+
+}
diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp
new file mode 100644
index 0000000..819fd36
--- /dev/null
+++ b/WebCore/plugins/qt/PluginViewQt.cpp
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginView.h"
+
+#include <QWidget>
+#include <QX11EmbedContainer>
+#include <QX11Info>
+
+#include "NotImplemented.h"
+#include "PluginDebug.h"
+#include "PluginPackage.h"
+#include "npruntime_impl.h"
+#include "runtime.h"
+#include "runtime_root.h"
+#include <runtime/JSLock.h>
+#include <runtime/JSValue.h>
+#include "JSDOMBinding.h"
+#include "ScriptController.h"
+
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "Element.h"
+#include "FrameLoader.h"
+#include "FrameLoadRequest.h"
+#include "FrameTree.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "HTMLNames.h"
+#include "HTMLPlugInElement.h"
+#include "KeyboardEvent.h"
+#include "MouseEvent.h"
+#include "Page.h"
+#include "PlatformMouseEvent.h"
+#include "RenderLayer.h"
+#include "Settings.h"
+
+using JSC::ExecState;
+using JSC::Interpreter;
+using JSC::JSLock;
+using JSC::JSObject;
+using JSC::UString;
+
+using std::min;
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+void PluginView::updatePluginWidget() const
+{
+ if (!parent() || !m_isWindowed)
+ return;
+
+ ASSERT(parent()->isFrameView());
+ FrameView* frameView = static_cast<FrameView*>(parent());
+
+ IntRect oldWindowRect = m_windowRect;
+ IntRect oldClipRect = m_clipRect;
+
+ m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size());
+ m_clipRect = windowClipRect();
+ m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
+
+ if (platformPluginWidget()) {
+ platformPluginWidget()->move(m_windowRect.x(), m_windowRect.y());
+ platformPluginWidget()->resize(m_windowRect.width(), m_windowRect.height());
+ platformPluginWidget()->setMask(QRegion(m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height()));
+ }
+}
+
+void PluginView::setFocus()
+{
+ if (platformPluginWidget())
+ platformPluginWidget()->setFocus(Qt::OtherFocusReason);
+ else
+ Widget::setFocus();
+}
+
+void PluginView::show()
+{
+ setSelfVisible(true);
+
+ if (isParentVisible() && platformPluginWidget())
+ platformPluginWidget()->setVisible(true);
+
+ Widget::show();
+}
+
+void PluginView::hide()
+{
+ setSelfVisible(false);
+
+ if (isParentVisible() && platformPluginWidget())
+ platformPluginWidget()->setVisible(false);
+
+ Widget::hide();
+}
+
+void PluginView::paint(GraphicsContext* context, const IntRect& rect)
+{
+ if (!m_isStarted) {
+ // Draw the "missing plugin" image
+ //paintMissingPluginIcon(context, rect);
+ return;
+ }
+
+ if (m_isWindowed || context->paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void PluginView::handleKeyboardEvent(KeyboardEvent* event)
+{
+ notImplemented();
+}
+
+void PluginView::handleMouseEvent(MouseEvent* event)
+{
+ notImplemented();
+}
+
+void PluginView::setParent(ScrollView* parent)
+{
+ Widget::setParent(parent);
+
+ if (parent)
+ init();
+ else {
+ if (!platformPluginWidget())
+ return;
+ }
+}
+
+void PluginView::setNPWindowRect(const IntRect& rect)
+{
+ if (!m_isStarted || !parent())
+ return;
+
+ IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(rect.location());
+ m_npWindow.x = p.x();
+ m_npWindow.y = p.y();
+
+ m_npWindow.width = rect.width();
+ m_npWindow.height = rect.height();
+
+ m_npWindow.clipRect.left = 0;
+ m_npWindow.clipRect.top = 0;
+ m_npWindow.clipRect.right = rect.width();
+ m_npWindow.clipRect.bottom = rect.height();
+
+ if (m_npWindow.x < 0 || m_npWindow.y < 0 ||
+ m_npWindow.width <= 0 || m_npWindow.height <= 0)
+ return;
+
+ if (m_plugin->pluginFuncs()->setwindow) {
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+
+ if (!m_isWindowed)
+ return;
+
+ ASSERT(platformPluginWidget());
+ }
+}
+
+void PluginView::setParentVisible(bool visible)
+{
+ if (isParentVisible() == visible)
+ return;
+
+ Widget::setParentVisible(visible);
+
+ if (isSelfVisible() && platformPluginWidget())
+ platformPluginWidget()->setVisible(visible);
+}
+
+void PluginView::stop()
+{
+ if (!m_isStarted)
+ return;
+
+ HashSet<RefPtr<PluginStream> > streams = m_streams;
+ HashSet<RefPtr<PluginStream> >::iterator end = streams.end();
+ for (HashSet<RefPtr<PluginStream> >::iterator it = streams.begin(); it != end; ++it) {
+ (*it)->stop();
+ disconnectStream((*it).get());
+ }
+
+ ASSERT(m_streams.isEmpty());
+
+ m_isStarted = false;
+
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+
+ // Clear the window
+ m_npWindow.window = 0;
+ delete (NPSetWindowCallbackStruct *)m_npWindow.ws_info;
+ m_npWindow.ws_info = 0;
+ if (m_plugin->pluginFuncs()->setwindow && !m_plugin->quirks().contains(PluginQuirkDontSetNullWindowHandleOnDestroy)) {
+ PluginView::setCurrentPluginView(this);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+
+ // Destroy the plugin
+ {
+ PluginView::setCurrentPluginView(this);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->destroy(m_instance, 0);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+
+ m_instance->pdata = 0;
+}
+
+static const char* MozillaUserAgent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0";
+
+const char* PluginView::userAgent()
+{
+ if (m_plugin->quirks().contains(PluginQuirkWantsMozillaUserAgent))
+ return MozillaUserAgent;
+
+ if (m_userAgent.isNull())
+ m_userAgent = m_parentFrame->loader()->userAgent(m_url).utf8();
+
+ return m_userAgent.data();
+}
+
+const char* PluginView::userAgentStatic()
+{
+ //FIXME - Just say we are Mozilla
+ return MozillaUserAgent;
+}
+
+NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf)
+{
+ String filename(buf, len);
+
+ if (filename.startsWith("file:///"))
+ filename = filename.substring(8);
+
+ if (!fileExists(filename))
+ return NPERR_FILE_NOT_FOUND;
+
+ //FIXME - read the file data into buffer
+ FILE* fileHandle = fopen((filename.utf8()).data(), "r");
+
+ if (fileHandle == 0)
+ return NPERR_FILE_NOT_FOUND;
+
+ //buffer.resize();
+
+ int bytesRead = fread(buffer.data(), 1, 0, fileHandle);
+
+ fclose(fileHandle);
+
+ if (bytesRead <= 0)
+ return NPERR_FILE_NOT_FOUND;
+
+ return NPERR_NO_ERROR;
+}
+
+NPError PluginView::getValueStatic(NPNVariable variable, void* value)
+{
+ switch (variable) {
+ case NPNVToolkit:
+ *((uint32 *)value) = 0;
+ return NPERR_NO_ERROR;
+
+ case NPNVSupportsXEmbedBool:
+ *((uint32 *)value) = true;
+ return NPERR_NO_ERROR;
+
+ case NPNVjavascriptEnabledBool:
+ *((uint32 *)value) = true;
+ return NPERR_NO_ERROR;
+
+ default:
+ return NPERR_GENERIC_ERROR;
+ }
+}
+
+NPError PluginView::getValue(NPNVariable variable, void* value)
+{
+ switch (variable) {
+ case NPNVxDisplay:
+ if (platformPluginWidget())
+ *(void **)value = platformPluginWidget()->x11Info().display();
+ else
+ *(void **)value = m_parentFrame->view()->hostWindow()->platformWindow()->x11Info().display();
+ return NPERR_NO_ERROR;
+
+ case NPNVxtAppContext:
+ return NPERR_GENERIC_ERROR;
+
+#if ENABLE(NETSCAPE_PLUGIN_API)
+ case NPNVWindowNPObject: {
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
+ NPObject* windowScriptObject = m_parentFrame->script()->windowScriptNPObject();
+
+ // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html>
+ if (windowScriptObject)
+ _NPN_RetainObject(windowScriptObject);
+
+ void** v = (void**)value;
+ *v = windowScriptObject;
+
+ return NPERR_NO_ERROR;
+ }
+
+ case NPNVPluginElementNPObject: {
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
+ NPObject* pluginScriptObject = 0;
+
+ if (m_element->hasTagName(appletTag) || m_element->hasTagName(embedTag) || m_element->hasTagName(objectTag))
+ pluginScriptObject = static_cast<HTMLPlugInElement*>(m_element)->getNPObject();
+
+ // Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html>
+ if (pluginScriptObject)
+ _NPN_RetainObject(pluginScriptObject);
+
+ void** v = (void**)value;
+ *v = pluginScriptObject;
+
+ return NPERR_NO_ERROR;
+ }
+#endif
+
+ case NPNVnetscapeWindow: {
+ void* w = reinterpret_cast<void*>(value);
+ *((XID *)w) = m_parentFrame->view()->hostWindow()->platformWindow()->winId();
+ return NPERR_NO_ERROR;
+ }
+
+ default:
+ return getValueStatic(variable, value);
+ }
+}
+
+void PluginView::invalidateRect(const IntRect& rect)
+{
+ if (platformWidget()) {
+ platformWidget()->update(rect);
+ return;
+ }
+
+ invalidateWindowlessPluginRect(rect);
+}
+
+void PluginView::invalidateRect(NPRect* rect)
+{
+ notImplemented();
+}
+
+void PluginView::invalidateRegion(NPRegion region)
+{
+ notImplemented();
+}
+
+void PluginView::forceRedraw()
+{
+ notImplemented();
+}
+
+PluginView::~PluginView()
+{
+ stop();
+
+ deleteAllValues(m_requests);
+
+ freeStringArray(m_paramNames, m_paramCount);
+ freeStringArray(m_paramValues, m_paramCount);
+
+ m_parentFrame->script()->cleanupScriptObjectsForPlugin(this);
+
+ if (m_plugin && !(m_plugin->quirks().contains(PluginQuirkDontUnloadPlugin)))
+ m_plugin->unload();
+
+ delete platformPluginWidget();
+}
+
+void PluginView::init()
+{
+ if (m_haveInitialized)
+ return;
+ m_haveInitialized = true;
+
+ if (!m_plugin) {
+ ASSERT(m_status == PluginStatusCanNotFindPlugin);
+ return;
+ }
+
+ if (!m_plugin->load()) {
+ m_plugin = 0;
+ m_status = PluginStatusCanNotLoadPlugin;
+ return;
+ }
+
+ if (!start()) {
+ m_status = PluginStatusCanNotLoadPlugin;
+ return;
+ }
+
+ if (m_plugin->pluginFuncs()->getvalue) {
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginNeedsXEmbed, &m_needsXEmbed);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ }
+
+ if (m_needsXEmbed) {
+ setPlatformWidget(new QX11EmbedContainer(m_parentFrame->view()->hostWindow()->platformWindow()));
+ setIsNPAPIPlugin(true);
+ } else {
+ notImplemented();
+ m_status = PluginStatusCanNotLoadPlugin;
+ return;
+ }
+ show ();
+
+ NPSetWindowCallbackStruct *wsi = new NPSetWindowCallbackStruct();
+
+ wsi->type = 0;
+
+ wsi->display = platformPluginWidget()->x11Info().display();
+ wsi->visual = (Visual*)platformPluginWidget()->x11Info().visual();
+ wsi->depth = platformPluginWidget()->x11Info().depth();
+ wsi->colormap = platformPluginWidget()->x11Info().colormap();
+ m_npWindow.ws_info = wsi;
+
+ m_npWindow.type = NPWindowTypeWindow;
+ m_npWindow.window = (void*)platformPluginWidget()->winId();
+
+ if (!(m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)))
+ setNPWindowRect(frameRect());
+
+ m_status = PluginStatusLoadedSuccessfully;
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/win/PluginDataWin.cpp b/WebCore/plugins/win/PluginDataWin.cpp
new file mode 100644
index 0000000..4ec4b6d
--- /dev/null
+++ b/WebCore/plugins/win/PluginDataWin.cpp
@@ -0,0 +1,72 @@
+/*
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "PluginData.h"
+
+#include "PluginDatabase.h"
+#include "PluginPackage.h"
+
+namespace WebCore {
+
+void PluginData::initPlugins()
+{
+ PluginDatabase *db = PluginDatabase::installedPlugins();
+ const Vector<PluginPackage*> &plugins = db->plugins();
+
+ for (unsigned int i = 0; i < plugins.size(); ++i) {
+ PluginInfo* info = new PluginInfo;
+ PluginPackage* package = plugins[i];
+
+ info->name = package->name();
+ info->file = package->fileName();
+ info->desc = package->description();
+
+ const MIMEToDescriptionsMap& mimeToDescriptions = package->mimeToDescriptions();
+ MIMEToDescriptionsMap::const_iterator end = mimeToDescriptions.end();
+ for (MIMEToDescriptionsMap::const_iterator it = mimeToDescriptions.begin(); it != end; ++it) {
+ MimeClassInfo* mime = new MimeClassInfo;
+ info->mimes.append(mime);
+
+ mime->type = it->first;
+ mime->desc = it->second;
+ mime->plugin = info;
+
+ Vector<String> extensions = package->mimeToExtensions().get(mime->type);
+
+ for (unsigned i = 0; i < extensions.size(); i++) {
+ if (i > 0)
+ mime->suffixes += ",";
+
+ mime->suffixes += extensions[i];
+ }
+ }
+
+ m_plugins.append(info);
+ }
+}
+
+void PluginData::refresh()
+{
+ PluginDatabase *db = PluginDatabase::installedPlugins();
+ db->refresh();
+}
+
+};
diff --git a/WebCore/plugins/win/PluginDatabaseWin.cpp b/WebCore/plugins/win/PluginDatabaseWin.cpp
index be8a253..c59f133 100644
--- a/WebCore/plugins/win/PluginDatabaseWin.cpp
+++ b/WebCore/plugins/win/PluginDatabaseWin.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,100 +27,19 @@
#include "config.h"
#include "PluginDatabase.h"
-#include "PluginPackage.h"
-#include "PluginView.h"
#include "Frame.h"
+#include "KURL.h"
+#include "PluginPackage.h"
#include <windows.h>
#include <shlwapi.h>
-namespace WebCore {
-
-PluginDatabase* PluginDatabase::installedPlugins()
-{
- static PluginDatabase* plugins = 0;
-
- if (!plugins) {
- plugins = new PluginDatabase;
- plugins->setPluginPaths(PluginDatabase::defaultPluginPaths());
- plugins->refresh();
- }
-
- return plugins;
-}
-
-void PluginDatabase::addExtraPluginPath(const String& path)
-{
- m_pluginPaths.append(path);
- refresh();
-}
-
-bool PluginDatabase::refresh()
-{
- PluginSet newPlugins;
-
- bool pluginSetChanged = false;
-
- // Create a new set of plugins
- newPlugins = getPluginsInPaths();
-
- if (!m_plugins.isEmpty()) {
- m_registeredMIMETypes.clear();
-
- PluginSet pluginsToUnload = m_plugins;
+#if COMPILER(MINGW)
+#define _countof(x) (sizeof(x)/sizeof(x[0]))
+#endif
- PluginSet::const_iterator end = newPlugins.end();
- for (PluginSet::const_iterator it = newPlugins.begin(); it != end; ++it)
- pluginsToUnload.remove(*it);
-
- end = m_plugins.end();
- for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it)
- newPlugins.remove(*it);
-
- // Unload plugins
- end = pluginsToUnload.end();
- for (PluginSet::const_iterator it = pluginsToUnload.begin(); it != end; ++it)
- m_plugins.remove(*it);
-
- // Add new plugins
- end = newPlugins.end();
- for (PluginSet::const_iterator it = newPlugins.begin(); it != end; ++it)
- m_plugins.add(*it);
-
- pluginSetChanged = !pluginsToUnload.isEmpty() || !newPlugins.isEmpty();
- } else {
- m_plugins = newPlugins;
- PluginSet::const_iterator end = newPlugins.end();
- for (PluginSet::const_iterator it = newPlugins.begin(); it != end; ++it)
- m_plugins.add(*it);
-
- pluginSetChanged = !newPlugins.isEmpty();
- }
-
- // Register plug-in MIME types
- PluginSet::const_iterator end = m_plugins.end();
- for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
- // Get MIME types
- MIMEToDescriptionsMap::const_iterator map_end = (*it)->mimeToDescriptions().end();
- for (MIMEToDescriptionsMap::const_iterator map_it = (*it)->mimeToDescriptions().begin(); map_it != map_end; ++map_it) {
- m_registeredMIMETypes.add(map_it->first);
- }
- }
-
- return pluginSetChanged;
-}
-
-Vector<PluginPackage*> PluginDatabase::plugins() const
-{
- Vector<PluginPackage*> result;
-
- PluginSet::const_iterator end = m_plugins.end();
- for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it)
- result.append((*it).get());
-
- return result;
-}
+namespace WebCore {
-static inline void addPluginsFromRegistry(HKEY rootKey, PluginSet& plugins)
+static inline void addPluginPathsFromRegistry(HKEY rootKey, HashSet<String>& paths)
{
HKEY key;
HRESULT result = RegOpenKeyExW(rootKey, L"Software\\MozillaPlugins", 0, KEY_ENUMERATE_SUB_KEYS, &key);
@@ -146,33 +66,25 @@ static inline void addPluginsFromRegistry(HKEY rootKey, PluginSet& plugins)
if (result != ERROR_SUCCESS || type != REG_SZ)
continue;
- WIN32_FILE_ATTRIBUTE_DATA attributes;
- if (GetFileAttributesEx(pathStr, GetFileExInfoStandard, &attributes) == 0)
- continue;
-
- PluginPackage* package = PluginPackage::createPackage(String(pathStr, pathStrSize / sizeof(WCHAR) - 1), attributes.ftLastWriteTime);
-
- if (package)
- plugins.add(package);
+ paths.add(String(pathStr, pathStrSize / sizeof(WCHAR) - 1));
}
RegCloseKey(key);
}
-PluginSet PluginDatabase::getPluginsInPaths() const
+void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const
{
// FIXME: This should be a case insensitive set.
HashSet<String> uniqueFilenames;
- PluginSet plugins;
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAW findFileData;
- PluginPackage* oldWMPPlugin = 0;
- PluginPackage* newWMPPlugin = 0;
+ String oldWMPPluginPath;
+ String newWMPPluginPath;
- Vector<String>::const_iterator end = m_pluginPaths.end();
- for (Vector<String>::const_iterator it = m_pluginPaths.begin(); it != end; ++it) {
+ Vector<String>::const_iterator end = m_pluginDirectories.end();
+ for (Vector<String>::const_iterator it = m_pluginDirectories.begin(); it != end; ++it) {
String pattern = *it + "\\*";
hFind = FindFirstFileW(pattern.charactersWithNullTermination(), &findFileData);
@@ -192,32 +104,26 @@ PluginSet PluginDatabase::getPluginsInPaths() const
String fullPath = *it + "\\" + filename;
if (!uniqueFilenames.add(fullPath).second)
continue;
-
- PluginPackage* pluginPackage = PluginPackage::createPackage(fullPath, findFileData.ftLastWriteTime);
- if (pluginPackage) {
- plugins.add(pluginPackage);
+ paths.add(fullPath);
- if (equalIgnoringCase(filename, "npdsplay.dll"))
- oldWMPPlugin = pluginPackage;
- else if (equalIgnoringCase(filename, "np-mswmp.dll"))
- newWMPPlugin = pluginPackage;
- }
+ if (equalIgnoringCase(filename, "npdsplay.dll"))
+ oldWMPPluginPath = fullPath;
+ else if (equalIgnoringCase(filename, "np-mswmp.dll"))
+ newWMPPluginPath = fullPath;
} while (FindNextFileW(hFind, &findFileData) != 0);
FindClose(hFind);
}
- addPluginsFromRegistry(HKEY_LOCAL_MACHINE, plugins);
- addPluginsFromRegistry(HKEY_CURRENT_USER, plugins);
+ addPluginPathsFromRegistry(HKEY_LOCAL_MACHINE, paths);
+ addPluginPathsFromRegistry(HKEY_CURRENT_USER, paths);
// If both the old and new WMP plugin are present in the plugins set,
// we remove the old one so we don't end up choosing the old one.
- if (oldWMPPlugin && newWMPPlugin)
- plugins.remove(oldWMPPlugin);
-
- return plugins;
+ if (!oldWMPPluginPath.isEmpty() && !newWMPPluginPath.isEmpty())
+ paths.remove(oldWMPPluginPath);
}
static inline Vector<int> parseVersionString(const String& versionString)
@@ -258,7 +164,7 @@ static inline bool compareVersions(const Vector<int>& versionA, const Vector<int
return false;
}
-static inline void addMozillaPluginPaths(Vector<String>& paths)
+static inline void addMozillaPluginDirectories(Vector<String>& directories)
{
// Enumerate all Mozilla plugin directories in the registry
HKEY key;
@@ -284,15 +190,15 @@ static inline void addMozillaPluginPaths(Vector<String>& paths)
result = RegOpenKeyEx(key, extensionsPath.charactersWithNullTermination(), 0, KEY_READ, &extensionsKey);
if (result == ERROR_SUCCESS) {
- // Now get the plugins path
- WCHAR pluginsPathStr[_MAX_PATH];
- DWORD pluginsPathSize = sizeof(pluginsPathStr);
+ // Now get the plugins directory
+ WCHAR pluginsDirectoryStr[_MAX_PATH];
+ DWORD pluginsDirectorySize = sizeof(pluginsDirectoryStr);
DWORD type;
- result = RegQueryValueEx(extensionsKey, TEXT("Plugins"), 0, &type, (LPBYTE)&pluginsPathStr, &pluginsPathSize);
+ result = RegQueryValueEx(extensionsKey, TEXT("Plugins"), 0, &type, (LPBYTE)&pluginsDirectoryStr, &pluginsDirectorySize);
if (result == ERROR_SUCCESS && type == REG_SZ)
- paths.append(String(pluginsPathStr, pluginsPathSize / sizeof(WCHAR) - 1));
+ directories.append(String(pluginsDirectoryStr, pluginsDirectorySize / sizeof(WCHAR) - 1));
RegCloseKey(extensionsKey);
}
@@ -302,14 +208,14 @@ static inline void addMozillaPluginPaths(Vector<String>& paths)
}
}
-static inline void addWindowsMediaPlayerPluginPath(Vector<String>& paths)
+static inline void addWindowsMediaPlayerPluginDirectory(Vector<String>& directories)
{
// The new WMP Firefox plugin is installed in \PFiles\Plugins if it can't find any Firefox installs
WCHAR pluginDirectoryStr[_MAX_PATH + 1];
DWORD pluginDirectorySize = ::ExpandEnvironmentStringsW(TEXT("%SYSTEMDRIVE%\\PFiles\\Plugins"), pluginDirectoryStr, _countof(pluginDirectoryStr));
if (pluginDirectorySize > 0 && pluginDirectorySize <= _countof(pluginDirectoryStr))
- paths.append(String(pluginDirectoryStr, pluginDirectorySize - 1));
+ directories.append(String(pluginDirectoryStr, pluginDirectorySize - 1));
DWORD type;
WCHAR installationDirectoryStr[_MAX_PATH];
@@ -318,10 +224,10 @@ static inline void addWindowsMediaPlayerPluginPath(Vector<String>& paths)
HRESULT result = SHGetValue(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\MediaPlayer"), TEXT("Installation Directory"), &type, (LPBYTE)&installationDirectoryStr, &installationDirectorySize);
if (result == ERROR_SUCCESS && type == REG_SZ)
- paths.append(String(installationDirectoryStr, installationDirectorySize / sizeof(WCHAR) - 1));
+ directories.append(String(installationDirectoryStr, installationDirectorySize / sizeof(WCHAR) - 1));
}
-static inline void addQuickTimePluginPath(Vector<String>& paths)
+static inline void addQuickTimePluginDirectory(Vector<String>& directories)
{
DWORD type;
WCHAR installationDirectoryStr[_MAX_PATH];
@@ -331,11 +237,11 @@ static inline void addQuickTimePluginPath(Vector<String>& paths)
if (result == ERROR_SUCCESS && type == REG_SZ) {
String pluginDir = String(installationDirectoryStr, installationDirectorySize / sizeof(WCHAR) - 1) + "\\plugins";
- paths.append(pluginDir);
+ directories.append(pluginDir);
}
}
-static inline void addAdobeAcrobatPluginPath(Vector<String>& paths)
+static inline void addAdobeAcrobatPluginDirectory(Vector<String>& directories)
{
HKEY key;
HRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Adobe\\Acrobat Reader"), 0, KEY_READ, &key);
@@ -372,22 +278,22 @@ static inline void addAdobeAcrobatPluginPath(Vector<String>& paths)
result = SHGetValue(HKEY_LOCAL_MACHINE, acrobatPluginKeyPath.charactersWithNullTermination(), 0, &type, (LPBYTE)acrobatInstallPathStr, &acrobatInstallPathSize);
if (result == ERROR_SUCCESS) {
- String acrobatPluginPath = String(acrobatInstallPathStr, acrobatInstallPathSize / sizeof(WCHAR) - 1) + "\\browser";
- paths.append(acrobatPluginPath);
+ String acrobatPluginDirectory = String(acrobatInstallPathStr, acrobatInstallPathSize / sizeof(WCHAR) - 1) + "\\browser";
+ directories.append(acrobatPluginDirectory);
}
}
RegCloseKey(key);
}
-static inline String safariPluginsPath()
+static inline String safariPluginsDirectory()
{
WCHAR moduleFileNameStr[_MAX_PATH];
- static String pluginsPath;
- static bool cachedPluginPath = false;
+ static String pluginsDirectory;
+ static bool cachedPluginDirectory = false;
- if (!cachedPluginPath) {
- cachedPluginPath = true;
+ if (!cachedPluginDirectory) {
+ cachedPluginDirectory = true;
int moduleFileNameLen = GetModuleFileName(0, moduleFileNameStr, _MAX_PATH);
@@ -397,13 +303,13 @@ static inline String safariPluginsPath()
if (!PathRemoveFileSpec(moduleFileNameStr))
goto exit;
- pluginsPath = String(moduleFileNameStr) + "\\Plugins";
+ pluginsDirectory = String(moduleFileNameStr) + "\\Plugins";
}
exit:
- return pluginsPath;
+ return pluginsDirectory;
}
-static inline void addMacromediaPluginPaths(Vector<String>& paths)
+static inline void addMacromediaPluginDirectories(Vector<String>& directories)
{
WCHAR systemDirectoryStr[MAX_PATH];
@@ -413,128 +319,36 @@ static inline void addMacromediaPluginPaths(Vector<String>& paths)
WCHAR macromediaDirectoryStr[MAX_PATH];
PathCombine(macromediaDirectoryStr, systemDirectoryStr, TEXT("macromed\\Flash"));
- paths.append(macromediaDirectoryStr);
+ directories.append(macromediaDirectoryStr);
PathCombine(macromediaDirectoryStr, systemDirectoryStr, TEXT("macromed\\Shockwave 10"));
- paths.append(macromediaDirectoryStr);
+ directories.append(macromediaDirectoryStr);
}
-Vector<String> PluginDatabase::defaultPluginPaths()
+Vector<String> PluginDatabase::defaultPluginDirectories()
{
- Vector<String> paths;
- String ourPath = safariPluginsPath();
-
- if (!ourPath.isNull())
- paths.append(ourPath);
- addQuickTimePluginPath(paths);
- addAdobeAcrobatPluginPath(paths);
- addMozillaPluginPaths(paths);
- addWindowsMediaPlayerPluginPath(paths);
- addMacromediaPluginPaths(paths);
-
- return paths;
+ Vector<String> directories;
+ String ourDirectory = safariPluginsDirectory();
+
+ if (!ourDirectory.isNull())
+ directories.append(ourDirectory);
+ addQuickTimePluginDirectory(directories);
+ addAdobeAcrobatPluginDirectory(directories);
+ addMozillaPluginDirectories(directories);
+ addWindowsMediaPlayerPluginDirectory(directories);
+ addMacromediaPluginDirectories(directories);
+
+ return directories;
}
-bool PluginDatabase::isMIMETypeRegistered(const String& mimeType)
+bool PluginDatabase::isPreferredPluginDirectory(const String& directory)
{
- if (mimeType.isNull())
- return false;
- if (m_registeredMIMETypes.contains(mimeType))
- return true;
- // No plugin was found, try refreshing the database and searching again
- return (refresh() && m_registeredMIMETypes.contains(mimeType));
-}
+ String ourDirectory = safariPluginsDirectory();
-PluginPackage* PluginDatabase::pluginForMIMEType(const String& mimeType)
-{
- if (mimeType.isEmpty())
- return 0;
-
- String key = mimeType.lower();
- String ourPath = safariPluginsPath();
- PluginPackage* plugin = 0;
- PluginSet::const_iterator end = m_plugins.end();
-
- for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
- if ((*it)->mimeToDescriptions().contains(key)) {
- plugin = (*it).get();
- // prefer plugins in our own plugins directory
- if (plugin->parentDirectory() == ourPath)
- break;
- }
- }
-
- return plugin;
-}
+ if (!ourDirectory.isNull() && !directory.isNull())
+ return ourDirectory == directory;
-String PluginDatabase::MIMETypeForExtension(const String& extension) const
-{
- if (extension.isEmpty())
- return String();
-
- PluginSet::const_iterator end = m_plugins.end();
- String ourPath = safariPluginsPath();
- String mimeType;
- PluginPackage* plugin = 0;
-
- for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
- MIMEToExtensionsMap::const_iterator mime_end = (*it)->mimeToExtensions().end();
-
- for (MIMEToExtensionsMap::const_iterator mime_it = (*it)->mimeToExtensions().begin(); mime_it != mime_end; ++mime_it) {
- const Vector<String>& extensions = mime_it->second;
- for (unsigned i = 0; i < extensions.size(); i++) {
- if (equalIgnoringCase(extensions[i], extension)) {
- mimeType = mime_it->first;
- plugin = (*it).get();
- // prefer plugins in our own plugins directory
- if (plugin->parentDirectory() == ourPath)
- break;
- }
- }
- }
- }
-
- return mimeType;
-}
-
-PluginPackage* PluginDatabase::findPlugin(const KURL& url, String& mimeType)
-{
- PluginPackage* plugin = pluginForMIMEType(mimeType);
- String filename = url.string();
-
- if (!plugin) {
- String filename = url.lastPathComponent();
- if (!filename.endsWith("/")) {
- int extensionPos = filename.reverseFind('.');
- if (extensionPos != -1) {
- String extension = filename.substring(extensionPos + 1);
-
- mimeType = MIMETypeForExtension(extension);
- plugin = pluginForMIMEType(mimeType);
- }
- }
- }
-
- // FIXME: if no plugin could be found, query Windows for the mime type
- // corresponding to the extension.
-
- return plugin;
-}
-
-PluginView* PluginDatabase::createPluginView(Frame* parentFrame, const IntSize& size, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
-{
- // if we fail to find a plugin for this MIME type, findPlugin will search for
- // a plugin by the file extension and update the MIME type, so pass a mutable String
- String mimeTypeCopy = mimeType;
- PluginPackage* plugin = findPlugin(url, mimeTypeCopy);
-
- // No plugin was found, try refreshing the database and searching again
- if (!plugin && refresh()) {
- mimeTypeCopy = mimeType;
- plugin = findPlugin(url, mimeTypeCopy);
- }
-
- return new PluginView(parentFrame, size, plugin, element, url, paramNames, paramValues, mimeTypeCopy, loadManually);
+ return false;
}
}
diff --git a/WebCore/plugins/win/PluginMessageThrottlerWin.cpp b/WebCore/plugins/win/PluginMessageThrottlerWin.cpp
new file mode 100644
index 0000000..27bf5b9
--- /dev/null
+++ b/WebCore/plugins/win/PluginMessageThrottlerWin.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginMessageThrottlerWin.h"
+
+#include "PluginView.h"
+#include <wtf/ASCIICType.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+static const double MessageThrottleTimeInterval = 0.001;
+
+PluginMessageThrottlerWin::PluginMessageThrottlerWin(PluginView* pluginView)
+ : m_back(0), m_front(0)
+ , m_pluginView(pluginView)
+ , m_messageThrottleTimer(this, &PluginMessageThrottlerWin::messageThrottleTimerFired)
+{
+ // Initialize the free list with our inline messages
+ for (unsigned i = 0; i < NumInlineMessages - 1; i++)
+ m_inlineMessages[i].next = &m_inlineMessages[i + 1];
+ m_inlineMessages[NumInlineMessages - 1].next = 0;
+ m_freeInlineMessages = &m_inlineMessages[0];
+}
+
+PluginMessageThrottlerWin::~PluginMessageThrottlerWin()
+{
+ PluginMessage* next;
+
+ for (PluginMessage* message = m_front; message; message = next) {
+ next = message->next;
+ freeMessage(message);
+ }
+}
+
+void PluginMessageThrottlerWin::appendMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ PluginMessage* message = allocateMessage();
+
+ message->hWnd = hWnd;
+ message->msg = msg;
+ message->wParam = wParam;
+ message->lParam = lParam;
+ message->next = 0;
+
+ if (m_back)
+ m_back->next = message;
+ m_back = message;
+ if (!m_front)
+ m_front = message;
+
+ if (!m_messageThrottleTimer.isActive())
+ m_messageThrottleTimer.startOneShot(MessageThrottleTimeInterval);
+}
+
+void PluginMessageThrottlerWin::messageThrottleTimerFired(Timer<PluginMessageThrottlerWin>*)
+{
+ PluginMessage* message = m_front;
+ m_front = m_front->next;
+ if (message == m_back)
+ m_back = 0;
+
+ ::CallWindowProc(m_pluginView->pluginWndProc(), message->hWnd, message->msg, message->wParam, message->lParam);
+
+ freeMessage(message);
+
+ if (m_front)
+ m_messageThrottleTimer.startOneShot(MessageThrottleTimeInterval);
+}
+
+PluginMessage* PluginMessageThrottlerWin::allocateMessage()
+{
+ PluginMessage *message;
+
+ if (m_freeInlineMessages) {
+ message = m_freeInlineMessages;
+ m_freeInlineMessages = message->next;
+ } else
+ message = new PluginMessage;
+
+ return message;
+}
+
+bool PluginMessageThrottlerWin::isInlineMessage(PluginMessage* message)
+{
+ return message >= &m_inlineMessages[0] && message <= &m_inlineMessages[NumInlineMessages - 1];
+}
+
+void PluginMessageThrottlerWin::freeMessage(PluginMessage* message)
+{
+ if (isInlineMessage(message)) {
+ message->next = m_freeInlineMessages;
+ m_freeInlineMessages = message;
+ } else
+ delete message;
+}
+
+} // namespace WebCore
diff --git a/WebCore/plugins/win/PluginMessageThrottlerWin.h b/WebCore/plugins/win/PluginMessageThrottlerWin.h
new file mode 100644
index 0000000..c74beab
--- /dev/null
+++ b/WebCore/plugins/win/PluginMessageThrottlerWin.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PluginMessageThrottlerWin_h
+#define PluginMessageThrottlerWin_h
+
+#include "Timer.h"
+
+#include <windows.h>
+
+namespace WebCore {
+ class PluginView;
+
+ struct PluginMessage {
+ HWND hWnd;
+ UINT msg;
+ WPARAM wParam;
+ LPARAM lParam;
+
+ struct PluginMessage* next;
+ };
+
+ class PluginMessageThrottlerWin {
+ public:
+ PluginMessageThrottlerWin(PluginView*);
+ ~PluginMessageThrottlerWin();
+
+ void appendMessage(HWND, UINT msg, WPARAM, LPARAM);
+
+ private:
+ void messageThrottleTimerFired(Timer<PluginMessageThrottlerWin>*);
+ PluginMessage* allocateMessage();
+ bool isInlineMessage(PluginMessage* message);
+ void freeMessage(PluginMessage* message);
+
+ PluginView* m_pluginView;
+ PluginMessage* m_back;
+ PluginMessage* m_front;
+
+ static const int NumInlineMessages = 4;
+ PluginMessage m_inlineMessages[NumInlineMessages];
+ PluginMessage* m_freeInlineMessages;
+
+ Timer<PluginMessageThrottlerWin> m_messageThrottleTimer;
+ };
+
+} // namespace WebCore
+
+#endif // PluginMessageThrottlerWin_h
diff --git a/WebCore/plugins/win/PluginPackageWin.cpp b/WebCore/plugins/win/PluginPackageWin.cpp
index c744822..d2c26e2 100644
--- a/WebCore/plugins/win/PluginPackageWin.cpp
+++ b/WebCore/plugins/win/PluginPackageWin.cpp
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,129 +24,57 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <shlwapi.h>
#include "config.h"
#include "PluginPackage.h"
+#include "CString.h"
+#include "MIMETypeRegistry.h"
+#include "PluginDatabase.h"
+#include "PluginDebug.h"
#include "Timer.h"
-#include "DeprecatedString.h"
#include "npruntime_impl.h"
-#include "PluginDebug.h"
+#include <string.h>
+#include <wtf/OwnArrayPtr.h>
+#include <shlwapi.h>
namespace WebCore {
-PluginPackage::~PluginPackage()
-{
- ASSERT(!m_isLoaded);
-}
-
static String getVersionInfo(const LPVOID versionInfoData, const String& info)
{
LPVOID buffer;
UINT bufferLength;
String subInfo = "\\StringfileInfo\\040904E4\\" + info;
-
- bool retval = VerQueryValueW(versionInfoData, const_cast<UChar*>(subInfo.charactersWithNullTermination()),
- &buffer, &bufferLength);
+ bool retval = VerQueryValueW(versionInfoData,
+ const_cast<UChar*>(subInfo.charactersWithNullTermination()),
+ &buffer, &bufferLength);
if (!retval || bufferLength == 0)
return String();
- // Subtract 1 from the length; we don't want the trailing 0
+ // Subtract 1 from the length; we don't want the trailing null character.
return String(reinterpret_cast<UChar*>(buffer), bufferLength - 1);
}
-static Vector<String> splitString(const String& str, char delimiter, int padTo)
-{
- int pos = 0;
- int newPos;
- Vector<String> result;
- DeprecatedString ds = str.deprecatedString();
- String s;
- do {
-
- newPos = ds.find(delimiter, pos);
-
- if (newPos == -1)
- s = ds.mid(pos);
- else
- s = ds.mid(pos, newPos - pos);
-
- if (!s.isEmpty())
- result.append(s);
-
- pos = newPos + 1;
- } while (newPos != -1);
-
- while (padTo != -1 && static_cast<int>(result.size()) < padTo)
- result.append("");
-
- return result;
-}
-
-void PluginPackage::freeLibrarySoon()
-{
- ASSERT(!m_freeLibraryTimer.isActive());
- ASSERT(m_module);
- ASSERT(m_loadCount == 0);
-
- m_freeLibraryTimer.startOneShot(0);
-}
-
-void PluginPackage::freeLibraryTimerFired(Timer<PluginPackage>* /*timer*/)
-{
- ASSERT(m_module);
- ASSERT(m_loadCount == 0);
-
- ::FreeLibrary(m_module);
- m_module = 0;
-}
-
-PluginPackage::PluginPackage(const String& path, const FILETIME& lastModified)
- : m_path(path)
- , m_module(0)
- , m_lastModified(lastModified)
- , m_isLoaded(false)
- , m_loadCount(0)
- , m_freeLibraryTimer(this, &PluginPackage::freeLibraryTimerFired)
- , m_fileVersionLS(0)
- , m_fileVersionMS(0)
-{
- m_fileName = String(PathFindFileName(m_path.charactersWithNullTermination()));
- m_parentDirectory = m_path.left(m_path.length() - m_fileName.length() - 1);
-}
-
-int PluginPackage::compareFileVersion(unsigned compareVersionMS, unsigned compareVersionLS) const
+int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const
{
// return -1, 0, or 1 if plug-in version is less than, equal to, or greater than
// the passed version
- if (m_fileVersionMS != compareVersionMS)
- return m_fileVersionMS > compareVersionMS ? 1 : -1;
- if (m_fileVersionLS != compareVersionLS)
- return m_fileVersionLS > compareVersionLS ? 1 : -1;
+ if (m_moduleVersion.mostSig != compareVersion.mostSig)
+ return m_moduleVersion.mostSig > compareVersion.mostSig ? 1 : -1;
+ if (m_moduleVersion.leastSig != compareVersion.leastSig)
+ return m_moduleVersion.leastSig > compareVersion.leastSig ? 1 : -1;
return 0;
}
-void PluginPackage::storeFileVersion(LPVOID versionInfoData)
-{
- VS_FIXEDFILEINFO* info;
- UINT infoSize;
- if (!VerQueryValue(versionInfoData, TEXT("\\"), (LPVOID*) &info, &infoSize) || infoSize < sizeof(VS_FIXEDFILEINFO))
- return;
- m_fileVersionLS = info->dwFileVersionLS;
- m_fileVersionMS = info->dwFileVersionMS;
-}
-
bool PluginPackage::isPluginBlacklisted()
{
- static const unsigned silverlightPluginMinRequiredVersionMS = 0x00010000;
- static const unsigned silverlightPluginMinRequiredVersionLS = 0x51BE0000;
-
if (name() == "Silverlight Plug-In") {
// workaround for <rdar://5557379> Crash in Silverlight when opening microsoft.com.
// the latest 1.0 version of Silverlight does not reproduce this crash, so allow it
// and any newer versions
- if (compareFileVersion(silverlightPluginMinRequiredVersionMS, silverlightPluginMinRequiredVersionLS) < 0)
+ static const PlatformModuleVersion slPluginMinRequired(0x51BE0000, 0x00010000);
+
+ if (compareFileVersion(slPluginMinRequired) < 0)
return true;
} else if (fileName() == "npmozax.dll")
// Bug 15217: Mozilla ActiveX control complains about missing xpcom_core.dll
@@ -154,58 +83,138 @@ bool PluginPackage::isPluginBlacklisted()
return false;
}
+void PluginPackage::determineQuirks(const String& mimeType)
+{
+ if (mimeType == "application/x-shockwave-flash") {
+ static const PlatformModuleVersion flashTenVersion(0x00000000, 0x000a0000);
+
+ // Pre 10 Flash only requests windowless plugins if we return a mozilla user agent
+ if (compareFileVersion(flashTenVersion) < 0)
+ m_quirks.add(PluginQuirkWantsMozillaUserAgent);
+
+ m_quirks.add(PluginQuirkThrottleInvalidate);
+ m_quirks.add(PluginQuirkThrottleWMUserPlusOneMessages);
+ m_quirks.add(PluginQuirkFlashURLNotifyBug);
+ }
+
+ if (name().contains("Microsoft") && name().contains("Windows Media")) {
+ // The WMP plugin sets its size on the first NPP_SetWindow call and never updates its size, so
+ // call SetWindow when the plugin view has a correct size
+ m_quirks.add(PluginQuirkDeferFirstSetWindowCall);
+
+ // Windowless mode does not work at all with the WMP plugin so just remove that parameter
+ // and don't pass it to the plug-in.
+ m_quirks.add(PluginQuirkRemoveWindowlessVideoParam);
+
+ // WMP has a modal message loop that it enters whenever we call it or
+ // ask it to paint. This modal loop can deliver messages to other
+ // windows in WebKit at times when they are not expecting them (for
+ // example, delivering a WM_PAINT message during a layout), and these
+ // can cause crashes.
+ m_quirks.add(PluginQuirkHasModalMessageLoop);
+ }
+
+ if (name() == "VLC Multimedia Plugin") {
+ // VLC hangs on NPP_Destroy if we call NPP_SetWindow with a null window handle
+ m_quirks.add(PluginQuirkDontSetNullWindowHandleOnDestroy);
+
+ // VLC 0.8.6d and 0.8.6e crash if multiple instances are created.
+ // <rdar://problem/5773070> tracks allowing multiple instances when this
+ // bug is fixed.
+ m_quirks.add(PluginQuirkDontAllowMultipleInstances);
+ }
+
+ // The DivX plugin sets its size on the first NPP_SetWindow call and never updates its size, so
+ // call SetWindow when the plugin view has a correct size
+ if (mimeType == "video/divx")
+ m_quirks.add(PluginQuirkDeferFirstSetWindowCall);
+
+ // FIXME: This is a workaround for a problem in our NPRuntime bindings; if a plug-in creates an
+ // NPObject and passes it to a function it's not possible to see what root object that NPObject belongs to.
+ // Thus, we don't know that the object should be invalidated when the plug-in instance goes away.
+ // See <rdar://problem/5487742>.
+ if (mimeType == "application/x-silverlight")
+ m_quirks.add(PluginQuirkDontUnloadPlugin);
+
+ if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) {
+ // Because a single process cannot create multiple VMs, and we cannot reliably unload a
+ // Java VM, we cannot unload the Java plugin, or we'll lose reference to our only VM
+ m_quirks.add(PluginQuirkDontUnloadPlugin);
+
+ // Setting the window region to an empty region causes bad scrolling repaint problems
+ // with the Java plug-in.
+ m_quirks.add(PluginQuirkDontClipToZeroRectWhenScrolling);
+ }
+
+ if (mimeType == "audio/x-pn-realaudio-plugin") {
+ // Prevent the Real plugin from calling the Window Proc recursively, causing the stack to overflow.
+ m_quirks.add(PluginQuirkDontCallWndProcForSameMessageRecursively);
+
+ static const PlatformModuleVersion lastKnownUnloadableRealPlayerVersion(0x000B0B24, 0x00060000);
+
+ // Unloading RealPlayer versions newer than 10.5 can cause a hang; see rdar://5669317.
+ // FIXME: Resume unloading when this bug in the RealPlayer Plug-In is fixed (rdar://5713147)
+ if (compareFileVersion(lastKnownUnloadableRealPlayerVersion) > 0)
+ m_quirks.add(PluginQuirkDontUnloadPlugin);
+ }
+}
+
bool PluginPackage::fetchInfo()
{
DWORD versionInfoSize, zeroHandle;
versionInfoSize = GetFileVersionInfoSizeW(m_path.charactersWithNullTermination(), &zeroHandle);
-
if (versionInfoSize == 0)
return false;
- LPVOID versionInfoData = fastMalloc(versionInfoSize);
+ OwnArrayPtr<char> versionInfoData(new char[versionInfoSize]);
- if (!GetFileVersionInfoW(m_path.charactersWithNullTermination(), 0, versionInfoSize, versionInfoData)) {
- fastFree(versionInfoData);
+ if (!GetFileVersionInfoW(m_path.charactersWithNullTermination(), 0, versionInfoSize, versionInfoData.get()))
return false;
- }
-
- m_name = getVersionInfo(versionInfoData, "ProductName");
- m_description = getVersionInfo(versionInfoData, "FileDescription");
- if (m_name.isNull() || m_description.isNull()) {
- fastFree(versionInfoData);
+ m_name = getVersionInfo(versionInfoData.get(), "ProductName");
+ m_description = getVersionInfo(versionInfoData.get(), "FileDescription");
+ if (m_name.isNull() || m_description.isNull())
return false;
- }
- storeFileVersion(versionInfoData);
+ VS_FIXEDFILEINFO* info;
+ UINT infoSize;
+ if (!VerQueryValue(versionInfoData.get(), TEXT("\\"), (LPVOID*) &info, &infoSize) || infoSize < sizeof(VS_FIXEDFILEINFO))
+ return false;
+ m_moduleVersion.leastSig = info->dwFileVersionLS;
+ m_moduleVersion.mostSig = info->dwFileVersionMS;
- if (isPluginBlacklisted()) {
- fastFree(versionInfoData);
+ if (isPluginBlacklisted())
return false;
- }
- Vector<String> mimeTypes = splitString(getVersionInfo(versionInfoData, "MIMEType"), '|', -1);
- Vector<String> fileExtents = splitString(getVersionInfo(versionInfoData, "FileExtents"), '|', mimeTypes.size());
- Vector<String> descriptions = splitString(getVersionInfo(versionInfoData, "FileOpenName"), '|', mimeTypes.size());
+ Vector<String> types;
+ getVersionInfo(versionInfoData.get(), "MIMEType").split('|', types);
+ Vector<String> extensionLists;
+ getVersionInfo(versionInfoData.get(), "FileExtents").split('|', extensionLists);
+ Vector<String> descriptions;
+ getVersionInfo(versionInfoData.get(), "FileOpenName").split('|', descriptions);
+
+ for (unsigned i = 0; i < types.size(); i++) {
+ String type = types[i].lower();
+ String description = i < descriptions.size() ? descriptions[i] : "";
+ String extensionList = i < extensionLists.size() ? extensionLists[i] : "";
- fastFree(versionInfoData);
+ Vector<String> extensionsVector;
+ extensionList.split(',', extensionsVector);
- for (unsigned i = 0; i < mimeTypes.size(); i++) {
- // Get rid of the extension list in the description string
- String description = descriptions[i];
+ // Get rid of the extension list that may be at the end of the description string.
int pos = description.find("(*");
if (pos != -1) {
- // There might be a space that we need to get rid of
+ // There might be a space that we need to get rid of.
if (pos > 1 && description[pos - 1] == ' ')
pos--;
-
description = description.left(pos);
}
- mimeTypes[i] = mimeTypes[i].lower();
+ // Determine the quirks for the MIME types this plug-in supports
+ determineQuirks(type);
- m_mimeToExtensions.add(mimeTypes[i], splitString(fileExtents[i], ',', -1));
- m_mimeToDescriptions.add(mimeTypes[i], description);
+ m_mimeToExtensions.add(type, extensionsVector);
+ m_mimeToDescriptions.add(type, description);
}
return true;
@@ -217,6 +226,8 @@ bool PluginPackage::load()
ASSERT(m_module);
m_freeLibraryTimer.stop();
} else if (m_isLoaded) {
+ if (m_quirks.contains(PluginQuirkDontAllowMultipleInstances))
+ return false;
m_loadCount++;
return true;
} else {
@@ -267,6 +278,7 @@ bool PluginPackage::load()
memset(&m_browserFuncs, 0, sizeof(m_browserFuncs));
m_browserFuncs.size = sizeof (m_browserFuncs);
m_browserFuncs.version = NP_VERSION_MINOR;
+
m_browserFuncs.geturl = NPN_GetURL;
m_browserFuncs.posturl = NPN_PostURL;
m_browserFuncs.requestread = NPN_RequestRead;
@@ -290,6 +302,7 @@ bool PluginPackage::load()
m_browserFuncs.getJavaPeer = NPN_GetJavaPeer;
m_browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState;
m_browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState;
+ m_browserFuncs.pluginthreadasynccall = NPN_PluginThreadAsyncCall;
m_browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
m_browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
@@ -311,6 +324,7 @@ bool PluginPackage::load()
m_browserFuncs.hasmethod = _NPN_HasMethod;
m_browserFuncs.setexception = _NPN_SetException;
m_browserFuncs.enumerate = _NPN_Enumerate;
+ m_browserFuncs.construct = _NPN_Construct;
npErr = NP_Initialize(&m_browserFuncs);
LOG_NPERROR(npErr);
@@ -320,69 +334,41 @@ bool PluginPackage::load()
m_loadCount++;
return true;
+
abort:
unloadWithoutShutdown();
return false;
}
-void PluginPackage::unload()
-{
- if (!m_isLoaded)
- return;
-
- if (--m_loadCount > 0)
- return;
-
- m_NPP_Shutdown();
-
- unloadWithoutShutdown();
-}
-
-void PluginPackage::unloadWithoutShutdown()
-{
- if (!m_isLoaded)
- return;
-
- ASSERT(m_loadCount == 0);
- ASSERT(m_module);
-
- // <rdar://5530519>: Crash when closing tab with pdf file (Reader 7 only)
- // If the plugin has subclassed its parent window, as with Reader 7, we may have
- // gotten here by way of the plugin's internal window proc forwarding a message to our
- // original window proc. If we free the plugin library from here, we will jump back
- // to code we just freed when we return, so delay calling FreeLibrary at least until
- // the next message loop
- freeLibrarySoon();
-
- m_isLoaded = false;
-}
-
-PluginPackage* PluginPackage::createPackage(const String& path, const FILETIME& lastModified)
-{
- PluginPackage* package = new PluginPackage(path, lastModified);
-
- if (!package->fetchInfo()) {
- delete package;
- return 0;
- }
-
- return package;
-}
-
unsigned PluginPackage::hash() const
{
- unsigned hashCodes[3] = {
+ const unsigned hashCodes[] = {
+ m_name.impl()->hash(),
m_description.impl()->hash(),
- m_lastModified.dwLowDateTime,
- m_lastModified.dwHighDateTime
+ m_mimeToExtensions.size()
};
- return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), 3 * sizeof(unsigned) / sizeof(UChar));
+ return StringImpl::computeHash(reinterpret_cast<const UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
}
bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b)
{
- return a.m_description == b.m_description && (CompareFileTime(&a.m_lastModified, &b.m_lastModified) == 0);
+ if (a.m_name != b.m_name)
+ return false;
+
+ if (a.m_description != b.m_description)
+ return false;
+
+ if (a.m_mimeToExtensions.size() != b.m_mimeToExtensions.size())
+ return false;
+
+ MIMEToExtensionsMap::const_iterator::Keys end = a.m_mimeToExtensions.end().keys();
+ for (MIMEToExtensionsMap::const_iterator::Keys it = a.m_mimeToExtensions.begin().keys(); it != end; ++it) {
+ if (!b.m_mimeToExtensions.contains(*it))
+ return false;
+ }
+
+ return true;
}
}
diff --git a/WebCore/plugins/win/PluginViewWin.cpp b/WebCore/plugins/win/PluginViewWin.cpp
index b219fa5..127d3fc 100644
--- a/WebCore/plugins/win/PluginViewWin.cpp
+++ b/WebCore/plugins/win/PluginViewWin.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
+ * Copyright (C) 2008 Collabora Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
*/
#include "config.h"
+
#include "PluginView.h"
#include "Document.h"
@@ -40,6 +41,7 @@
#include "Image.h"
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
+#include "JSDOMWindow.h"
#include "KeyboardEvent.h"
#include "MIMETypeRegistry.h"
#include "MouseEvent.h"
@@ -47,25 +49,42 @@
#include "Page.h"
#include "FocusController.h"
#include "PlatformMouseEvent.h"
+#include "PluginMessageThrottlerWin.h"
#include "PluginPackage.h"
-#include "kjs_binding.h"
-#include "kjs_proxy.h"
-#include "kjs_window.h"
+#include "PluginMainThreadScheduler.h"
+#include "JSDOMBinding.h"
+#include "ScriptController.h"
+#include "PluginDatabase.h"
#include "PluginDebug.h"
#include "PluginPackage.h"
+#include "c_instance.h"
#include "npruntime_impl.h"
#include "runtime_root.h"
#include "Settings.h"
-#include <kjs/JSLock.h>
-#include <kjs/value.h>
+#include "runtime.h"
+#include <runtime/JSLock.h>
+#include <runtime/JSValue.h>
#include <wtf/ASCIICType.h>
-using KJS::ExecState;
-using KJS::JSLock;
-using KJS::JSObject;
-using KJS::JSValue;
-using KJS::UString;
-using KJS::Window;
+#if PLATFORM(QT)
+#include <QWidget.h>
+#endif
+
+static inline HWND windowHandleForPlatformWidget(PlatformWidget widget)
+{
+#if PLATFORM(QT)
+ if (!widget)
+ return 0;
+ return widget->winId();
+#else
+ return widget;
+#endif
+}
+
+using JSC::ExecState;
+using JSC::JSLock;
+using JSC::JSObject;
+using JSC::UString;
using std::min;
@@ -73,156 +92,13 @@ using namespace WTF;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
-class PluginRequest {
-public:
- PluginRequest(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData, bool shouldAllowPopups)
- : m_frameLoadRequest(frameLoadRequest)
- , m_notifyData(notifyData)
- , m_sendNotification(sendNotification)
- , m_shouldAllowPopups(shouldAllowPopups) { }
-public:
- const FrameLoadRequest& frameLoadRequest() const { return m_frameLoadRequest; }
- void* notifyData() const { return m_notifyData; }
- bool sendNotification() const { return m_sendNotification; }
- bool shouldAllowPopups() const { return m_shouldAllowPopups; }
-private:
- FrameLoadRequest m_frameLoadRequest;
- void* m_notifyData;
- bool m_sendNotification;
- bool m_shouldAllowPopups;
-};
-
-static const double MessageThrottleTimeInterval = 0.001;
-static int s_callingPlugin;
-
-class PluginMessageThrottlerWin {
-public:
- PluginMessageThrottlerWin(PluginView* pluginView)
- : m_back(0), m_front(0)
- , m_pluginView(pluginView)
- , m_messageThrottleTimer(this, &PluginMessageThrottlerWin::messageThrottleTimerFired)
- {
- // Initialize the free list with our inline messages
- for (unsigned i = 0; i < NumInlineMessages - 1; i++)
- m_inlineMessages[i].next = &m_inlineMessages[i + 1];
- m_inlineMessages[NumInlineMessages - 1].next = 0;
- m_freeInlineMessages = &m_inlineMessages[0];
- }
-
- ~PluginMessageThrottlerWin()
- {
- PluginMessage* next;
-
- for (PluginMessage* message = m_front; message; message = next) {
- next = message->next;
- freeMessage(message);
- }
- }
-
- void appendMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- PluginMessage* message = allocateMessage();
-
- message->hWnd = hWnd;
- message->msg = msg;
- message->wParam = wParam;
- message->lParam = lParam;
- message->next = 0;
-
- if (m_back)
- m_back->next = message;
- m_back = message;
- if (!m_front)
- m_front = message;
-
- if (!m_messageThrottleTimer.isActive())
- m_messageThrottleTimer.startOneShot(MessageThrottleTimeInterval);
- }
-
-private:
- struct PluginMessage {
- HWND hWnd;
- UINT msg;
- WPARAM wParam;
- LPARAM lParam;
-
- struct PluginMessage* next;
- };
-
- void messageThrottleTimerFired(Timer<PluginMessageThrottlerWin>*)
- {
- PluginMessage* message = m_front;
- m_front = m_front->next;
- if (message == m_back)
- m_back = 0;
-
- ::CallWindowProc(m_pluginView->pluginWndProc(), message->hWnd, message->msg, message->wParam, message->lParam);
-
- freeMessage(message);
-
- if (m_front)
- m_messageThrottleTimer.startOneShot(MessageThrottleTimeInterval);
- }
-
- PluginMessage* allocateMessage()
- {
- PluginMessage *message;
-
- if (m_freeInlineMessages) {
- message = m_freeInlineMessages;
- m_freeInlineMessages = message->next;
- } else
- message = new PluginMessage;
-
- return message;
- }
-
- bool isInlineMessage(PluginMessage* message)
- {
- return message >= &m_inlineMessages[0] && message <= &m_inlineMessages[NumInlineMessages - 1];
- }
-
- void freeMessage(PluginMessage* message)
- {
- if (isInlineMessage(message)) {
- message->next = m_freeInlineMessages;
- m_freeInlineMessages = message;
- } else
- delete message;
- }
-
- PluginView* m_pluginView;
- PluginMessage* m_back;
- PluginMessage* m_front;
-
- static const int NumInlineMessages = 4;
- PluginMessage m_inlineMessages[NumInlineMessages];
- PluginMessage* m_freeInlineMessages;
-
- Timer<PluginMessageThrottlerWin> m_messageThrottleTimer;
-};
-
-static String scriptStringIfJavaScriptURL(const KURL& url)
-{
- if (!url.string().startsWith("javascript:", false))
- return String();
-
- // This returns an unescaped string
- return KURL::decode_string(url.deprecatedString().mid(11));
-}
-
-PluginView* PluginView::s_currentPluginView = 0;
-
const LPCWSTR kWebPluginViewdowClassName = L"WebPluginView";
const LPCWSTR kWebPluginViewProperty = L"WebPluginViewProperty";
static const char* MozillaUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0";
-static LRESULT CALLBACK PluginViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-
static bool registerPluginView()
{
static bool haveRegisteredWindowClass = false;
@@ -231,6 +107,10 @@ static bool registerPluginView()
haveRegisteredWindowClass = true;
+#if PLATFORM(QT)
+ Page::setInstanceHandle((HINSTANCE)(qWinAppInst()));
+#endif
+
ASSERT(Page::instanceHandle());
WNDCLASSEX wcex;
@@ -252,19 +132,13 @@ static bool registerPluginView()
return !!RegisterClassEx(&wcex);
}
-static LRESULT CALLBACK PluginViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+LRESULT CALLBACK PluginView::PluginViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PluginView* pluginView = reinterpret_cast<PluginView*>(GetProp(hWnd, kWebPluginViewProperty));
return pluginView->wndProc(hWnd, message, wParam, lParam);
}
-void PluginView::popPopupsStateTimerFired(Timer<PluginView>*)
-{
- popPopupsEnabledState();
-}
-
-
static bool isWindowsMessageUserGesture(UINT message)
{
switch (message) {
@@ -299,12 +173,12 @@ PluginView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
if (message == m_lastMessage &&
- m_quirks.contains(PluginQuirkDontCallWndProcForSameMessageRecursively) &&
+ m_plugin->quirks().contains(PluginQuirkDontCallWndProcForSameMessageRecursively) &&
m_isCallingPluginWndProc)
return 1;
if (message == WM_USER + 1 &&
- m_quirks.contains(PluginQuirkThrottleWMUserPlusOneMessages)) {
+ m_plugin->quirks().contains(PluginQuirkThrottleWMUserPlusOneMessages)) {
if (!m_messageThrottler)
m_messageThrottler.set(new PluginMessageThrottlerWin(this));
@@ -321,7 +195,7 @@ PluginView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
// pops up windows in response to a posted message.
if (m_plugin->pluginFuncs()->version < NPVERS_HAS_POPUPS_ENABLED_STATE &&
isWindowsMessageUserGesture(message) && !m_popPopupsStateTimer.isActive()) {
-
+
pushPopupsEnabledState(true);
m_popPopupsStateTimer.startOneShot(0);
@@ -335,7 +209,7 @@ PluginView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return result;
}
-void PluginView::updateWindow() const
+void PluginView::updatePluginWidget() const
{
if (!parent())
return;
@@ -346,11 +220,11 @@ void PluginView::updateWindow() const
IntRect oldWindowRect = m_windowRect;
IntRect oldClipRect = m_clipRect;
- m_windowRect = IntRect(frameView->contentsToWindow(frameGeometry().location()), frameGeometry().size());
+ m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size());
m_clipRect = windowClipRect();
m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
- if (m_window && (m_windowRect != oldWindowRect || m_clipRect != oldClipRect)) {
+ if (platformPluginWidget() && (m_windowRect != oldWindowRect || m_clipRect != oldClipRect)) {
HRGN rgn;
setCallingPlugin(true);
@@ -358,96 +232,66 @@ void PluginView::updateWindow() const
// To prevent flashes while scrolling, we disable drawing during the window
// update process by clipping the window to the zero rect.
- bool clipToZeroRect = !m_quirks.contains(PluginQuirkDontClipToZeroRectWhenScrolling);
+ bool clipToZeroRect = !m_plugin->quirks().contains(PluginQuirkDontClipToZeroRectWhenScrolling);
if (clipToZeroRect) {
rgn = ::CreateRectRgn(0, 0, 0, 0);
- ::SetWindowRgn(m_window, rgn, FALSE);
+ ::SetWindowRgn(platformPluginWidget(), rgn, FALSE);
} else {
rgn = ::CreateRectRgn(m_clipRect.x(), m_clipRect.y(), m_clipRect.right(), m_clipRect.bottom());
- ::SetWindowRgn(m_window, rgn, TRUE);
+ ::SetWindowRgn(platformPluginWidget(), rgn, TRUE);
}
if (m_windowRect != oldWindowRect)
- ::MoveWindow(m_window, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), TRUE);
+ ::MoveWindow(platformPluginWidget(), m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), TRUE);
if (clipToZeroRect) {
rgn = ::CreateRectRgn(m_clipRect.x(), m_clipRect.y(), m_clipRect.right(), m_clipRect.bottom());
- ::SetWindowRgn(m_window, rgn, TRUE);
+ ::SetWindowRgn(platformPluginWidget(), rgn, TRUE);
}
setCallingPlugin(false);
}
}
-IntRect PluginView::windowClipRect() const
-{
- // Start by clipping to our bounds.
- IntRect clipRect(m_windowRect);
-
- // Take our element and get the clip rect from the enclosing layer and frame view.
- RenderLayer* layer = m_element->renderer()->enclosingLayer();
- FrameView* parentView = m_element->document()->view();
- clipRect.intersect(parentView->windowClipRectForLayer(layer, true));
-
- return clipRect;
-}
-
-void PluginView::setFrameGeometry(const IntRect& rect)
-{
- if (m_element->document()->printing())
- return;
-
- if (rect != frameGeometry())
- Widget::setFrameGeometry(rect);
-
- updateWindow();
- setNPWindowRect(rect);
-}
-
-void PluginView::geometryChanged() const
-{
- updateWindow();
-}
-
void PluginView::setFocus()
{
- if (m_window)
- SetFocus(m_window);
+ if (platformPluginWidget())
+ SetFocus(platformPluginWidget());
Widget::setFocus();
}
void PluginView::show()
{
- m_isVisible = true;
+ setSelfVisible(true);
- if (m_attachedToWindow && m_window)
- ShowWindow(m_window, SW_SHOWNA);
+ if (isParentVisible() && platformPluginWidget())
+ ShowWindow(platformPluginWidget(), SW_SHOWNA);
Widget::show();
}
void PluginView::hide()
{
- m_isVisible = false;
+ setSelfVisible(false);
- if (m_attachedToWindow && m_window)
- ShowWindow(m_window, SW_HIDE);
+ if (isParentVisible() && platformPluginWidget())
+ ShowWindow(platformPluginWidget(), SW_HIDE);
Widget::hide();
}
void PluginView::paintMissingPluginIcon(GraphicsContext* context, const IntRect& rect)
{
- static Image* nullPluginImage;
+ static RefPtr<Image> nullPluginImage;
if (!nullPluginImage)
nullPluginImage = Image::loadPlatformResource("nullPlugin");
- IntRect imageRect(frameGeometry().x(), frameGeometry().y(), nullPluginImage->width(), nullPluginImage->height());
+ IntRect imageRect(frameRect().x(), frameRect().y(), nullPluginImage->width(), nullPluginImage->height());
- int xOffset = (frameGeometry().width() - imageRect.width()) / 2;
- int yOffset = (frameGeometry().height() - imageRect.height()) / 2;
+ int xOffset = (frameRect().width() - imageRect.width()) / 2;
+ int yOffset = (frameRect().height() - imageRect.height()) / 2;
imageRect.move(xOffset, yOffset);
@@ -456,7 +300,7 @@ void PluginView::paintMissingPluginIcon(GraphicsContext* context, const IntRect&
context->save();
context->clip(windowClipRect());
- context->drawImage(nullPluginImage, imageRect.location());
+ context->drawImage(nullPluginImage.get(), imageRect.location());
context->restore();
}
@@ -472,7 +316,7 @@ bool PluginView::dispatchNPEvent(NPEvent& npEvent)
shouldPop = true;
}
- KJS::JSLock::DropAllLocks dropAllLocks;
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
setCallingPlugin(true);
bool result = m_plugin->pluginFuncs()->event(m_instance, &npEvent);
setCallingPlugin(false);
@@ -495,31 +339,36 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
return;
ASSERT(parent()->isFrameView());
- IntRect rectInWindow = static_cast<FrameView*>(parent())->contentsToWindow(frameGeometry());
+ IntRect rectInWindow = static_cast<FrameView*>(parent())->contentsToWindow(frameRect());
HDC hdc = context->getWindowsContext(rectInWindow, m_isTransparent);
NPEvent npEvent;
+ // On Safari/Windows without transparency layers the GraphicsContext returns the HDC
+ // of the window and the plugin expects that the passed in DC has window coordinates.
+ // In the Qt port we always draw in an offscreen buffer and therefore need to preserve
+ // the translation set in getWindowsContext.
+#if !PLATFORM(QT)
if (!context->inTransparencyLayer()) {
- // The plugin expects that the passed in DC has window coordinates.
XFORM transform;
GetWorldTransform(hdc, &transform);
transform.eDx = 0;
transform.eDy = 0;
SetWorldTransform(hdc, &transform);
}
+#endif
m_npWindow.type = NPWindowTypeDrawable;
m_npWindow.window = hdc;
- IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(frameGeometry().location());
+ IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(frameRect().location());
WINDOWPOS windowpos;
memset(&windowpos, 0, sizeof(windowpos));
windowpos.x = p.x();
windowpos.y = p.y();
- windowpos.cx = frameGeometry().width();
- windowpos.cy = frameGeometry().height();
+ windowpos.cx = frameRect().width();
+ windowpos.cy = frameRect().height();
npEvent.event = WM_WINDOWPOSCHANGED;
npEvent.lParam = reinterpret_cast<uint32>(&windowpos);
@@ -527,7 +376,7 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
dispatchNPEvent(npEvent);
- setNPWindowRect(frameGeometry());
+ setNPWindowRect(frameRect());
npEvent.event = WM_PAINT;
npEvent.wParam = reinterpret_cast<uint32>(hdc);
@@ -538,7 +387,7 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
dispatchNPEvent(npEvent);
- context->releaseWindowsContext(hdc, frameGeometry(), m_isTransparent);
+ context->releaseWindowsContext(hdc, frameRect(), m_isTransparent);
}
void PluginView::handleKeyboardEvent(KeyboardEvent* event)
@@ -547,15 +396,15 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event)
npEvent.wParam = event->keyCode();
- if (event->type() == keydownEvent) {
+ if (event->type() == eventNames().keydownEvent) {
npEvent.event = WM_KEYDOWN;
npEvent.lParam = 0;
- } else if (event->type() == keyupEvent) {
+ } else if (event->type() == eventNames().keyupEvent) {
npEvent.event = WM_KEYUP;
npEvent.lParam = 0x8000;
}
- KJS::JSLock::DropAllLocks;
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
if (!dispatchNPEvent(npEvent))
event->setDefaultHandled();
}
@@ -577,9 +426,9 @@ void PluginView::handleMouseEvent(MouseEvent* event)
if (event->shiftKey())
npEvent.wParam |= MK_SHIFT;
- if (event->type() == mousemoveEvent ||
- event->type() == mouseoutEvent ||
- event->type() == mouseoverEvent) {
+ if (event->type() == eventNames().mousemoveEvent ||
+ event->type() == eventNames().mouseoutEvent ||
+ event->type() == eventNames().mouseoverEvent) {
npEvent.event = WM_MOUSEMOVE;
if (event->buttonDown())
switch (event->button()) {
@@ -594,7 +443,7 @@ void PluginView::handleMouseEvent(MouseEvent* event)
break;
}
}
- else if (event->type() == mousedownEvent) {
+ else if (event->type() == eventNames().mousedownEvent) {
// Focus the plugin
if (Page* page = m_parentFrame->page())
page->focusController()->setFocusedFrame(m_parentFrame);
@@ -610,7 +459,7 @@ void PluginView::handleMouseEvent(MouseEvent* event)
npEvent.event = WM_RBUTTONDOWN;
break;
}
- } else if (event->type() == mouseupEvent) {
+ } else if (event->type() == eventNames().mouseupEvent) {
switch (event->button()) {
case 0:
npEvent.event = WM_LBUTTONUP;
@@ -627,25 +476,16 @@ void PluginView::handleMouseEvent(MouseEvent* event)
HCURSOR currentCursor = ::GetCursor();
- KJS::JSLock::DropAllLocks;
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
if (!dispatchNPEvent(npEvent))
event->setDefaultHandled();
+#if !PLATFORM(QT)
// Currently, Widget::setCursor is always called after this function in EventHandler.cpp
// and since we don't want that we set ignoreNextSetCursor to true here to prevent that.
ignoreNextSetCursor = true;
lastSetCursor = ::GetCursor();
-}
-
-void PluginView::handleEvent(Event* event)
-{
- if (!m_plugin || m_isWindowed)
- return;
-
- if (event->isMouseEvent())
- handleMouseEvent(static_cast<MouseEvent*>(event));
- else if (event->isKeyboardEvent())
- handleKeyboardEvent(static_cast<KeyboardEvent*>(event));
+#endif
}
void PluginView::setParent(ScrollView* parent)
@@ -655,37 +495,32 @@ void PluginView::setParent(ScrollView* parent)
if (parent)
init();
else {
- if (!m_window)
+ if (!platformPluginWidget())
return;
// If the plug-in window or one of its children have the focus, we need to
// clear it to prevent the web view window from being focused because that can
// trigger a layout while the plugin element is being detached.
HWND focusedWindow = ::GetFocus();
- if (m_window == focusedWindow || ::IsChild(m_window, focusedWindow))
+ if (platformPluginWidget() == focusedWindow || ::IsChild(platformPluginWidget(), focusedWindow))
::SetFocus(0);
}
}
-void PluginView::attachToWindow()
+void PluginView::setParentVisible(bool visible)
{
- if (m_attachedToWindow)
+ if (isParentVisible() == visible)
return;
- m_attachedToWindow = true;
- if (m_isVisible && m_window)
- ShowWindow(m_window, SW_SHOWNA);
-}
-
-void PluginView::detachFromWindow()
-{
- if (!m_attachedToWindow)
- return;
+ Widget::setParentVisible(visible);
- if (m_isVisible && m_window)
- ShowWindow(m_window, SW_HIDE);
- m_attachedToWindow = false;
+ if (isSelfVisible() && platformPluginWidget()) {
+ if (visible)
+ ShowWindow(platformPluginWidget(), SW_SHOWNA);
+ else
+ ShowWindow(platformPluginWidget(), SW_HIDE);
+ }
}
void PluginView::setNPWindowRect(const IntRect& rect)
@@ -706,7 +541,7 @@ void PluginView::setNPWindowRect(const IntRect& rect)
m_npWindow.clipRect.bottom = rect.height();
if (m_plugin->pluginFuncs()->setwindow) {
- KJS::JSLock::DropAllLocks dropAllLocks;
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
setCallingPlugin(true);
m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
setCallingPlugin(false);
@@ -714,46 +549,12 @@ void PluginView::setNPWindowRect(const IntRect& rect)
if (!m_isWindowed)
return;
- ASSERT(m_window);
+ ASSERT(platformPluginWidget());
- WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(m_window, GWLP_WNDPROC);
+ WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC);
if (currentWndProc != PluginViewWndProc)
- m_pluginWndProc = (WNDPROC)SetWindowLongPtr(m_window, GWLP_WNDPROC, (LONG)PluginViewWndProc);
- }
-}
-
-bool PluginView::start()
-{
- if (m_isStarted)
- return false;
-
- ASSERT(m_plugin);
- ASSERT(m_plugin->pluginFuncs()->newp);
-
- NPError npErr;
- PluginView::setCurrentPluginView(this);
- {
- KJS::JSLock::DropAllLocks dropAllLocks;
- setCallingPlugin(true);
- npErr = m_plugin->pluginFuncs()->newp((NPMIMEType)m_mimeType.data(), m_instance, m_mode, m_paramCount, m_paramNames, m_paramValues, NULL);
- setCallingPlugin(false);
- LOG_NPERROR(npErr);
- }
- PluginView::setCurrentPluginView(0);
-
- if (npErr != NPERR_NO_ERROR)
- return false;
-
- m_isStarted = true;
-
- if (!m_url.isEmpty() && !m_loadManually) {
- FrameLoadRequest frameLoadRequest;
- frameLoadRequest.resourceRequest().setHTTPMethod("GET");
- frameLoadRequest.resourceRequest().setURL(m_url);
- load(frameLoadRequest, false, 0);
+ m_pluginWndProc = (WNDPROC)SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG)PluginViewWndProc);
}
-
- return true;
}
void PluginView::stop()
@@ -774,22 +575,24 @@ void PluginView::stop()
// Unsubclass the window
if (m_isWindowed) {
- WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(m_window, GWLP_WNDPROC);
+ WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC);
if (currentWndProc == PluginViewWndProc)
- SetWindowLongPtr(m_window, GWLP_WNDPROC, (LONG)m_pluginWndProc);
+ SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG)m_pluginWndProc);
}
- KJS::JSLock::DropAllLocks;
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
// Clear the window
m_npWindow.window = 0;
- if (m_plugin->pluginFuncs()->setwindow && !m_quirks.contains(PluginQuirkDontSetNullWindowHandleOnDestroy)) {
+ if (m_plugin->pluginFuncs()->setwindow && !m_plugin->quirks().contains(PluginQuirkDontSetNullWindowHandleOnDestroy)) {
setCallingPlugin(true);
m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
setCallingPlugin(false);
}
+ PluginMainThreadScheduler::scheduler().unregisterPlugin(m_instance);
+
// Destroy the plugin
NPSavedData* savedData = 0;
setCallingPlugin(true);
@@ -806,489 +609,68 @@ void PluginView::stop()
m_instance->pdata = 0;
}
-void PluginView::setCurrentPluginView(PluginView* pluginView)
+const char* PluginView::userAgentStatic()
{
- s_currentPluginView = pluginView;
-}
-
-PluginView* PluginView::currentPluginView()
-{
- return s_currentPluginView;
-}
-
-static char* createUTF8String(const String& str)
-{
- CString cstr = str.utf8();
- char* result = reinterpret_cast<char*>(fastMalloc(cstr.length() + 1));
-
- strncpy(result, cstr.data(), cstr.length() + 1);
-
- return result;
-}
-
-static void freeStringArray(char** stringArray, int length)
-{
- if (!stringArray)
- return;
-
- for (int i = 0; i < length; i++)
- fastFree(stringArray[i]);
-
- fastFree(stringArray);
-}
-
-static bool getString(KJSProxy* proxy, JSValue* result, String& string)
-{
- if (!proxy || !result || result->isUndefined())
- return false;
- JSLock lock;
-
- ExecState* exec = proxy->globalObject()->globalExec();
- UString ustring = result->toString(exec);
- exec->clearException();
-
- string = ustring;
- return true;
-}
-
-void PluginView::performRequest(PluginRequest* request)
-{
- // don't let a plugin start any loads if it is no longer part of a document that is being
- // displayed unless the loads are in the same frame as the plugin.
- const String& targetFrameName = request->frameLoadRequest().frameName();
- if (m_parentFrame->loader()->documentLoader() != m_parentFrame->loader()->activeDocumentLoader() &&
- (targetFrameName.isNull() || m_parentFrame->tree()->find(targetFrameName) != m_parentFrame))
- return;
-
- KURL requestURL = request->frameLoadRequest().resourceRequest().url();
- String jsString = scriptStringIfJavaScriptURL(requestURL);
-
- if (jsString.isNull()) {
- // if this is not a targeted request, create a stream for it. otherwise,
- // just pass it off to the loader
- if (targetFrameName.isEmpty()) {
- PluginStream* stream = new PluginStream(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_quirks);
- m_streams.add(stream);
- stream->start();
- } else {
- m_parentFrame->loader()->load(request->frameLoadRequest().resourceRequest(), targetFrameName);
-
- // FIXME: <rdar://problem/4807469> This should be sent when the document has finished loading
- if (request->sendNotification()) {
- KJS::JSLock::DropAllLocks dropAllLocks;
- setCallingPlugin(true);
- m_plugin->pluginFuncs()->urlnotify(m_instance, requestURL.deprecatedString().utf8(), NPRES_DONE, request->notifyData());
- setCallingPlugin(false);
- }
- }
- return;
- }
-
- // Targeted JavaScript requests are only allowed on the frame that contains the JavaScript plugin
- // and this has been made sure in ::load.
- ASSERT(targetFrameName.isEmpty() || m_parentFrame->tree()->find(targetFrameName) == m_parentFrame);
-
- // Executing a script can cause the plugin view to be destroyed, so we keep a reference to the parent frame.
- RefPtr<Frame> parentFrame = m_parentFrame;
- JSValue* result = m_parentFrame->loader()->executeScript(jsString, request->shouldAllowPopups());
-
- if (targetFrameName.isNull()) {
- String resultString;
-
- CString cstr;
- if (getString(parentFrame->scriptProxy(), result, resultString))
- cstr = resultString.utf8();
-
- RefPtr<PluginStream> stream = new PluginStream(this, m_parentFrame, request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_quirks);
- m_streams.add(stream);
- stream->sendJavaScriptStream(requestURL, cstr);
- }
-}
-
-void PluginView::requestTimerFired(Timer<PluginView>* timer)
-{
- ASSERT(timer == &m_requestTimer);
- ASSERT(m_requests.size() > 0);
-
- PluginRequest* request = m_requests[0];
- m_requests.remove(0);
-
- // Schedule a new request before calling performRequest since the call to
- // performRequest can cause the plugin view to be deleted.
- if (m_requests.size() > 0)
- m_requestTimer.startOneShot(0);
-
- performRequest(request);
- delete request;
-}
-
-void PluginView::scheduleRequest(PluginRequest* request)
-{
- m_requests.append(request);
- m_requestTimer.startOneShot(0);
-}
-
-NPError PluginView::load(const FrameLoadRequest& frameLoadRequest, bool sendNotification, void* notifyData)
-{
- ASSERT(frameLoadRequest.resourceRequest().httpMethod() == "GET" || frameLoadRequest.resourceRequest().httpMethod() == "POST");
-
- KURL url = frameLoadRequest.resourceRequest().url();
-
- if (url.isEmpty())
- return NPERR_INVALID_URL;
-
- const String& targetFrameName = frameLoadRequest.frameName();
- String jsString = scriptStringIfJavaScriptURL(url);
-
- if (!jsString.isNull()) {
- Settings* settings = m_parentFrame->settings();
- if (!settings || !settings->isJavaScriptEnabled()) {
- // Return NPERR_GENERIC_ERROR if JS is disabled. This is what Mozilla does.
- return NPERR_GENERIC_ERROR;
- }
-
- if (!targetFrameName.isNull() && m_parentFrame->tree()->find(targetFrameName) != m_parentFrame) {
- // For security reasons, only allow JS requests to be made on the frame that contains the plug-in.
- return NPERR_INVALID_PARAM;
- }
- }
-
- PluginRequest* request = new PluginRequest(frameLoadRequest, sendNotification, notifyData, arePopupsAllowed());
- scheduleRequest(request);
-
- return NPERR_NO_ERROR;
-}
-
-static KURL makeURL(const KURL& baseURL, const char* relativeURLString)
-{
- DeprecatedString urlString = DeprecatedString::fromLatin1(relativeURLString);
-
- // Strip return characters
- urlString.replace('\n', "");
- urlString.replace('\r', "");
-
- return KURL(baseURL, urlString);
-}
-
-NPError PluginView::getURLNotify(const char* url, const char* target, void* notifyData)
-{
- FrameLoadRequest frameLoadRequest;
-
- frameLoadRequest.setFrameName(target);
- frameLoadRequest.resourceRequest().setHTTPMethod("GET");
- frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url));
-
- return load(frameLoadRequest, true, notifyData);
-}
-
-NPError PluginView::getURL(const char* url, const char* target)
-{
- FrameLoadRequest frameLoadRequest;
-
- frameLoadRequest.setFrameName(target);
- frameLoadRequest.resourceRequest().setHTTPMethod("GET");
- frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url));
-
- return load(frameLoadRequest, false, 0);
-}
-
-static inline bool startsWithBlankLine(const Vector<char>& buffer)
-{
- return buffer.size() > 0 && buffer[0] == '\n';
-}
-
-static inline int locationAfterFirstBlankLine(const Vector<char>& buffer)
-{
- const char* bytes = buffer.data();
- unsigned length = buffer.size();
-
- for (unsigned i = 0; i < length - 4; i++) {
- // Support for Acrobat. It sends "\n\n".
- if (bytes[i] == '\n' && bytes[i + 1] == '\n')
- return i + 2;
-
- // Returns the position after 2 CRLF's or 1 CRLF if it is the first line.
- if (bytes[i] == '\r' && bytes[i + 1] == '\n') {
- i += 2;
- if (i == 2)
- return i;
- else if (bytes[i] == '\n')
- // Support for Director. It sends "\r\n\n" (3880387).
- return i + 1;
- else if (bytes[i] == '\r' && bytes[i + 1] == '\n')
- // Support for Flash. It sends "\r\n\r\n" (3758113).
- return i + 2;
- }
- }
-
- return -1;
-}
-
-static inline const char* findEOL(const char* bytes, unsigned length)
-{
- // According to the HTTP specification EOL is defined as
- // a CRLF pair. Unfortunately, some servers will use LF
- // instead. Worse yet, some servers will use a combination
- // of both (e.g. <header>CRLFLF<body>), so findEOL needs
- // to be more forgiving. It will now accept CRLF, LF or
- // CR.
- //
- // It returns NULL if EOLF is not found or it will return
- // a pointer to the first terminating character.
- for (unsigned i = 0; i < length; i++) {
- if (bytes[i] == '\n')
- return bytes + i;
- if (bytes[i] == '\r') {
- // Check to see if spanning buffer bounds
- // (CRLF is across reads). If so, wait for
- // next read.
- if (i + 1 == length)
- break;
-
- return bytes + i;
- }
- }
-
return 0;
}
-static inline String capitalizeRFC822HeaderFieldName(const String& name)
-{
- bool capitalizeCharacter = true;
- String result;
-
- for (unsigned i = 0; i < name.length(); i++) {
- UChar c;
-
- if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z')
- c = toASCIIUpper(name[i]);
- else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z')
- c = toASCIILower(name[i]);
- else
- c = name[i];
-
- if (name[i] == '-')
- capitalizeCharacter = true;
- else
- capitalizeCharacter = false;
-
- result.append(c);
- }
-
- return result;
-}
-
-static inline HTTPHeaderMap parseRFC822HeaderFields(const Vector<char>& buffer, unsigned length)
+const char* PluginView::userAgent()
{
- const char* bytes = buffer.data();
- const char* eol;
- String lastKey;
- HTTPHeaderMap headerFields;
-
- // Loop ove rlines until we're past the header, or we can't find any more end-of-lines
- while ((eol = findEOL(bytes, length))) {
- const char* line = bytes;
- int lineLength = eol - bytes;
-
- // Move bytes to the character after the terminator as returned by findEOL.
- bytes = eol + 1;
- if ((*eol == '\r') && (*bytes == '\n'))
- bytes++; // Safe since findEOL won't return a spanning CRLF.
-
- length -= (bytes - line);
- if (lineLength == 0)
- // Blank line; we're at the end of the header
- break;
- else if (*line == ' ' || *line == '\t') {
- // Continuation of the previous header
- if (lastKey.isNull()) {
- // malformed header; ignore it and continue
- continue;
- } else {
- // Merge the continuation of the previous header
- String currentValue = headerFields.get(lastKey);
- String newValue = DeprecatedString::fromLatin1(line, lineLength);
-
- headerFields.set(lastKey, currentValue + newValue);
- }
- } else {
- // Brand new header
- const char* colon;
- for (colon = line; *colon != ':' && colon != eol; colon++) {
- // empty loop
- }
- if (colon == eol)
- // malformed header; ignore it and continue
- continue;
- else {
- lastKey = capitalizeRFC822HeaderFieldName(DeprecatedString::fromLatin1(line, colon - line));
- String value;
-
- for (colon++; colon != eol; colon++) {
- if (*colon != ' ' && *colon != '\t')
- break;
- }
- if (colon == eol)
- value = "";
- else
- value = DeprecatedString::fromLatin1(colon, eol - colon);
-
- String oldValue = headerFields.get(lastKey);
- if (!oldValue.isNull()) {
- String tmp = oldValue;
- tmp += ", ";
- tmp += value;
- value = tmp;
- }
-
- headerFields.set(lastKey, value);
- }
- }
- }
+ if (m_plugin->quirks().contains(PluginQuirkWantsMozillaUserAgent))
+ return MozillaUserAgent;
- return headerFields;
+ if (m_userAgent.isNull())
+ m_userAgent = m_parentFrame->loader()->userAgent(m_url).utf8();
+ return m_userAgent.data();
}
-NPError PluginView::handlePost(const char* url, const char* target, uint32 len, const char* buf, bool file, void* notifyData, bool sendNotification, bool allowHeaders)
+NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf)
{
- if (!url || !len || !buf)
- return NPERR_INVALID_PARAM;
-
- FrameLoadRequest frameLoadRequest;
-
- HTTPHeaderMap headerFields;
- Vector<char> buffer;
-
- if (file) {
- String filename = DeprecatedString::fromLatin1(buf, len);
-
- if (filename.startsWith("file:///"))
- filename = filename.substring(8);
-
- // Get file info
- WIN32_FILE_ATTRIBUTE_DATA attrs;
- if (GetFileAttributesExW(filename.charactersWithNullTermination(), GetFileExInfoStandard, &attrs) == 0)
- return NPERR_FILE_NOT_FOUND;
-
- if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- return NPERR_FILE_NOT_FOUND;
+ String filename(buf, len);
- HANDLE fileHandle = CreateFileW(filename.charactersWithNullTermination(), FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
-
- if (fileHandle == INVALID_HANDLE_VALUE)
- return NPERR_FILE_NOT_FOUND;
-
- buffer.resize(attrs.nFileSizeLow);
-
- DWORD bytesRead;
- int retval = ReadFile(fileHandle, buffer.data(), attrs.nFileSizeLow, &bytesRead, 0);
+ if (filename.startsWith("file:///"))
+ filename = filename.substring(8);
- CloseHandle(fileHandle);
+ // Get file info
+ WIN32_FILE_ATTRIBUTE_DATA attrs;
+ if (GetFileAttributesExW(filename.charactersWithNullTermination(), GetFileExInfoStandard, &attrs) == 0)
+ return NPERR_FILE_NOT_FOUND;
- if (retval == 0 || bytesRead != attrs.nFileSizeLow)
- return NPERR_FILE_NOT_FOUND;
- } else {
- buffer.resize(len);
- memcpy(buffer.data(), buf, len);
- }
+ if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ return NPERR_FILE_NOT_FOUND;
- const char* postData = buffer.data();
- int postDataLength = buffer.size();
+ HANDLE fileHandle = CreateFileW(filename.charactersWithNullTermination(), FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
- if (allowHeaders) {
- if (startsWithBlankLine(buffer)) {
- postData++;
- postDataLength--;
- } else {
- int location = locationAfterFirstBlankLine(buffer);
- if (location != -1) {
- // If the blank line is somewhere in the middle of the buffer, everything before is the header
- headerFields = parseRFC822HeaderFields(buffer, location);
- unsigned dataLength = buffer.size() - location;
-
- // Sometimes plugins like to set Content-Length themselves when they post,
- // but WebFoundation does not like that. So we will remove the header
- // and instead truncate the data to the requested length.
- String contentLength = headerFields.get("Content-Length");
-
- if (!contentLength.isNull())
- dataLength = min(contentLength.toInt(), (int)dataLength);
- headerFields.remove("Content-Length");
-
- postData += location;
- postDataLength = dataLength;
- }
- }
- }
-
- frameLoadRequest.resourceRequest().setHTTPMethod("POST");
- frameLoadRequest.resourceRequest().setURL(makeURL(m_baseURL, url));
- frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields);
- frameLoadRequest.resourceRequest().setHTTPBody(PassRefPtr<FormData>(new FormData(postData, postDataLength)));
- frameLoadRequest.setFrameName(target);
-
- return load(frameLoadRequest, sendNotification, notifyData);
-}
-
-NPError PluginView::postURLNotify(const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData)
-{
- return handlePost(url, target, len, buf, file, notifyData, true, true);
-}
+ if (fileHandle == INVALID_HANDLE_VALUE)
+ return NPERR_FILE_NOT_FOUND;
-NPError PluginView::postURL(const char* url, const char* target, uint32 len, const char* buf, NPBool file)
-{
- // As documented, only allow headers to be specified via NPP_PostURL when using a file.
- return handlePost(url, target, len, buf, file, 0, false, file);
-}
+ buffer.resize(attrs.nFileSizeLow);
-NPError PluginView::newStream(NPMIMEType type, const char* target, NPStream** stream)
-{
- notImplemented();
- // Unsupported
- return NPERR_GENERIC_ERROR;
-}
-
-int32 PluginView::write(NPStream* stream, int32 len, void* buffer)
-{
- notImplemented();
- // Unsupported
- return -1;
-}
+ DWORD bytesRead;
+ int retval = ReadFile(fileHandle, buffer.data(), attrs.nFileSizeLow, &bytesRead, 0);
-NPError PluginView::destroyStream(NPStream* stream, NPReason reason)
-{
- PluginStream* browserStream = static_cast<PluginStream*>(stream->ndata);
+ CloseHandle(fileHandle);
- if (!stream || PluginStream::ownerForStream(stream) != m_instance)
- return NPERR_INVALID_INSTANCE_ERROR;
+ if (retval == 0 || bytesRead != attrs.nFileSizeLow)
+ return NPERR_FILE_NOT_FOUND;
- browserStream->cancelAndDestroyStream(reason);
return NPERR_NO_ERROR;
}
-const char* PluginView::userAgent()
-{
- if (m_quirks.contains(PluginQuirkWantsMozillaUserAgent))
- return MozillaUserAgent;
-
- if (m_userAgent.isNull())
- m_userAgent = m_parentFrame->loader()->userAgent(m_url).utf8();
- return m_userAgent.data();
-}
-
-void PluginView::status(const char* message)
+NPError PluginView::getValueStatic(NPNVariable variable, void* value)
{
- String s = DeprecatedString::fromLatin1(message);
-
- if (Page* page = m_parentFrame->page())
- page->chrome()->setStatusbarText(m_parentFrame, s);
+ return NPERR_GENERIC_ERROR;
}
NPError PluginView::getValue(NPNVariable variable, void* value)
{
switch (variable) {
+#if ENABLE(NETSCAPE_PLUGIN_API)
case NPNVWindowNPObject: {
- NPObject* windowScriptObject = m_parentFrame->windowScriptNPObject();
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
+ NPObject* windowScriptObject = m_parentFrame->script()->windowScriptNPObject();
// Return value is expected to be retained, as described here: <http://www.mozilla.org/projects/plugin/npruntime.html>
if (windowScriptObject)
@@ -1296,11 +678,14 @@ NPError PluginView::getValue(NPNVariable variable, void* value)
void** v = (void**)value;
*v = windowScriptObject;
-
+
return NPERR_NO_ERROR;
}
case NPNVPluginElementNPObject: {
+ if (m_isJavaScriptPaused)
+ return NPERR_GENERIC_ERROR;
+
NPObject* pluginScriptObject = 0;
if (m_element->hasTagName(appletTag) || m_element->hasTagName(embedTag) || m_element->hasTagName(objectTag))
@@ -1315,44 +700,40 @@ NPError PluginView::getValue(NPNVariable variable, void* value)
return NPERR_NO_ERROR;
}
+#endif
case NPNVnetscapeWindow: {
HWND* w = reinterpret_cast<HWND*>(value);
- *w = containingWindow();
+ *w = windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0);
return NPERR_NO_ERROR;
}
- default:
- return NPERR_GENERIC_ERROR;
- }
-}
-NPError PluginView::setValue(NPPVariable variable, void* value)
-{
- switch (variable) {
- case NPPVpluginWindowBool:
- m_isWindowed = value;
- return NPERR_NO_ERROR;
- case NPPVpluginTransparentBool:
- m_isTransparent = value;
+ case NPNVSupportsWindowless: {
+ NPBool *result = reinterpret_cast<NPBool*>(value);
+
+ *result = TRUE;
+
return NPERR_NO_ERROR;
+ }
+
default:
- notImplemented();
return NPERR_GENERIC_ERROR;
}
}
-void PluginView::invalidateTimerFired(Timer<PluginView>* timer)
+void PluginView::invalidateRect(const IntRect& rect)
{
- ASSERT(timer == &m_invalidateTimer);
+ if (m_isWindowed) {
+ RECT invalidRect = { rect.x(), rect.y(), rect.right(), rect.bottom() };
+ ::InvalidateRect(platformPluginWidget(), &invalidRect, false);
+ return;
+ }
- for (unsigned i = 0; i < m_invalidRects.size(); i++)
- Widget::invalidateRect(m_invalidRects[i]);
- m_invalidRects.clear();
+ invalidateWindowlessPluginRect(rect);
}
-
void PluginView::invalidateRect(NPRect* rect)
{
if (!rect) {
@@ -1363,15 +744,15 @@ void PluginView::invalidateRect(NPRect* rect)
IntRect r(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
if (m_isWindowed) {
- RECT invalidRect(r);
- InvalidateRect(m_window, &invalidRect, FALSE);
+ RECT invalidRect = { r.x(), r.y(), r.right(), r.bottom() };
+ InvalidateRect(platformPluginWidget(), &invalidRect, FALSE);
} else {
- if (m_quirks.contains(PluginQuirkThrottleInvalidate)) {
+ if (m_plugin->quirks().contains(PluginQuirkThrottleInvalidate)) {
m_invalidRects.append(r);
if (!m_invalidateTimer.isActive())
m_invalidateTimer.startOneShot(0.001);
} else
- Widget::invalidateRect(r);
+ invalidateRect(r);
}
}
@@ -1387,59 +768,16 @@ void PluginView::invalidateRegion(NPRegion region)
return;
}
- Widget::invalidateRect(r);
+ IntRect rect(IntPoint(r.left, r.top), IntSize(r.right-r.left, r.bottom-r.top));
+ invalidateRect(rect);
}
void PluginView::forceRedraw()
{
if (m_isWindowed)
- ::UpdateWindow(m_window);
+ ::UpdateWindow(platformPluginWidget());
else
- ::UpdateWindow(containingWindow());
-}
-
-void PluginView::pushPopupsEnabledState(bool state)
-{
- m_popupStateStack.append(state);
-}
-
-void PluginView::popPopupsEnabledState()
-{
- m_popupStateStack.removeLast();
-}
-
-bool PluginView::arePopupsAllowed() const
-{
- if (!m_popupStateStack.isEmpty())
- return m_popupStateStack.last();
-
- return false;
-}
-
-KJS::Bindings::Instance* PluginView::bindingInstance()
-{
- NPObject* object = 0;
-
- if (!m_plugin || !m_plugin->pluginFuncs()->getvalue)
- return 0;
-
- NPError npErr;
- {
- KJS::JSLock::DropAllLocks dropAllLocks;
- setCallingPlugin(true);
- npErr = m_plugin->pluginFuncs()->getvalue(m_instance, NPPVpluginScriptableNPObject, &object);
- setCallingPlugin(false);
- }
-
- if (npErr != NPERR_NO_ERROR || !object)
- return 0;
-
- RefPtr<KJS::Bindings::RootObject> root = m_parentFrame->createRootObject(this, m_parentFrame->scriptProxy()->globalObject());
- KJS::Bindings::Instance *instance = KJS::Bindings::Instance::createBindingForLanguageInstance(KJS::Bindings::Instance::CLanguage, object, root.release());
-
- _NPN_ReleaseObject(object);
-
- return instance;
+ ::UpdateWindow(windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0));
}
PluginView::~PluginView()
@@ -1451,155 +789,15 @@ PluginView::~PluginView()
freeStringArray(m_paramNames, m_paramCount);
freeStringArray(m_paramValues, m_paramCount);
- if (m_window)
- DestroyWindow(m_window);
+ if (platformPluginWidget())
+ DestroyWindow(platformPluginWidget());
- m_parentFrame->cleanupScriptObjectsForPlugin(this);
+ m_parentFrame->script()->cleanupScriptObjectsForPlugin(this);
- if (m_plugin && !m_quirks.contains(PluginQuirkDontUnloadPlugin))
+ if (m_plugin && !m_plugin->quirks().contains(PluginQuirkDontUnloadPlugin))
m_plugin->unload();
}
-void PluginView::disconnectStream(PluginStream* stream)
-{
- ASSERT(m_streams.contains(stream));
-
- m_streams.remove(stream);
-}
-
-void PluginView::determineQuirks(const String& mimeType)
-{
- static const unsigned lastKnownUnloadableRealPlayerVersionLS = 0x000B0B24;
- static const unsigned lastKnownUnloadableRealPlayerVersionMS = 0x00060000;
-
- if (mimeType == "application/x-shockwave-flash") {
- // The flash plugin only requests windowless plugins if we return a mozilla user agent
- m_quirks.add(PluginQuirkWantsMozillaUserAgent);
- m_quirks.add(PluginQuirkThrottleInvalidate);
- m_quirks.add(PluginQuirkThrottleWMUserPlusOneMessages);
- m_quirks.add(PluginQuirkFlashURLNotifyBug);
- }
-
- if (m_plugin->name().contains("Microsoft") && m_plugin->name().contains("Windows Media")) {
- // The WMP plugin sets its size on the first NPP_SetWindow call and never updates its size, so
- // call SetWindow when the plugin view has a correct size
- m_quirks.add(PluginQuirkDeferFirstSetWindowCall);
-
- // Windowless mode does not work at all with the WMP plugin so just remove that parameter
- // and don't pass it to the plug-in.
- m_quirks.add(PluginQuirkRemoveWindowlessVideoParam);
-
- // WMP has a modal message loop that it enters whenever we call it or
- // ask it to paint. This modal loop can deliver messages to other
- // windows in WebKit at times when they are not expecting them (for
- // example, delivering a WM_PAINT message during a layout), and these
- // can cause crashes.
- m_quirks.add(PluginQuirkHasModalMessageLoop);
- }
-
- // VLC hangs on NPP_Destroy if we call NPP_SetWindow with a null window handle
- if (m_plugin->name() == "VLC Multimedia Plugin")
- m_quirks.add(PluginQuirkDontSetNullWindowHandleOnDestroy);
-
- // The DivX plugin sets its size on the first NPP_SetWindow call and never updates its size, so
- // call SetWindow when the plugin view has a correct size
- if (mimeType == "video/divx")
- m_quirks.add(PluginQuirkDeferFirstSetWindowCall);
-
- // FIXME: This is a workaround for a problem in our NPRuntime bindings; if a plug-in creates an
- // NPObject and passes it to a function it's not possible to see what root object that NPObject belongs to.
- // Thus, we don't know that the object should be invalidated when the plug-in instance goes away.
- // See <rdar://problem/5487742>.
- if (mimeType == "application/x-silverlight")
- m_quirks.add(PluginQuirkDontUnloadPlugin);
-
- if (MIMETypeRegistry::isJavaAppletMIMEType(mimeType)) {
- // Because a single process cannot create multiple VMs, and we cannot reliably unload a
- // Java VM, we cannot unload the Java plugin, or we'll lose reference to our only VM
- m_quirks.add(PluginQuirkDontUnloadPlugin);
-
- // Setting the window region to an empty region causes bad scrolling repaint problems
- // with the Java plug-in.
- m_quirks.add(PluginQuirkDontClipToZeroRectWhenScrolling);
- }
-
- if (mimeType == "audio/x-pn-realaudio-plugin") {
- // Prevent the Real plugin from calling the Window Proc recursively, causing the stack to overflow.
- m_quirks.add(PluginQuirkDontCallWndProcForSameMessageRecursively);
-
- // Unloading RealPlayer versions newer than 10.5 can cause a hang; see rdar://5669317.
- // FIXME: Resume unloading when this bug in the RealPlayer Plug-In is fixed (rdar://5713147)
- if (m_plugin->compareFileVersion(lastKnownUnloadableRealPlayerVersionMS, lastKnownUnloadableRealPlayerVersionLS) > 0)
- m_quirks.add(PluginQuirkDontUnloadPlugin);
- }
-}
-
-void PluginView::setParameters(const Vector<String>& paramNames, const Vector<String>& paramValues)
-{
- ASSERT(paramNames.size() == paramValues.size());
-
- unsigned size = paramNames.size();
- unsigned paramCount = 0;
-
- m_paramNames = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size));
- m_paramValues = reinterpret_cast<char**>(fastMalloc(sizeof(char*) * size));
-
- for (unsigned i = 0; i < size; i++) {
- if (m_quirks.contains(PluginQuirkRemoveWindowlessVideoParam) && equalIgnoringCase(paramNames[i], "windowlessvideo"))
- continue;
-
- m_paramNames[paramCount] = createUTF8String(paramNames[i]);
- m_paramValues[paramCount] = createUTF8String(paramValues[i]);
-
- paramCount++;
- }
-
- m_paramCount = paramCount;
-}
-
-PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* plugin, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
- : m_parentFrame(parentFrame)
- , m_plugin(plugin)
- , m_element(element)
- , m_isStarted(false)
- , m_url(url)
- , m_baseURL(m_parentFrame->loader()->completeURL(m_parentFrame->document()->baseURL()))
- , m_status(PluginStatusLoadedSuccessfully)
- , m_requestTimer(this, &PluginView::requestTimerFired)
- , m_invalidateTimer(this, &PluginView::invalidateTimerFired)
- , m_popPopupsStateTimer(this, &PluginView::popPopupsStateTimerFired)
- , m_paramNames(0)
- , m_paramValues(0)
- , m_window(0)
- , m_pluginWndProc(0)
- , m_isWindowed(true)
- , m_isTransparent(false)
- , m_isVisible(false)
- , m_attachedToWindow(false)
- , m_haveInitialized(false)
- , m_lastMessage(0)
- , m_isCallingPluginWndProc(false)
- , m_loadManually(loadManually)
- , m_manualStream(0)
-{
- if (!m_plugin) {
- m_status = PluginStatusCanNotFindPlugin;
- return;
- }
-
- m_instance = &m_instanceStruct;
- m_instance->ndata = this;
-
- m_mimeType = mimeType.utf8();
- determineQuirks(mimeType);
-
- setParameters(paramNames, paramValues);
-
- m_mode = m_loadManually ? NP_FULL : NP_EMBED;
-
- resize(size);
-}
-
void PluginView::init()
{
if (m_haveInitialized)
@@ -1626,82 +824,38 @@ void PluginView::init()
registerPluginView();
DWORD flags = WS_CHILD;
- if (m_isVisible)
+ if (isSelfVisible())
flags |= WS_VISIBLE;
- m_window = CreateWindowEx(0, kWebPluginViewdowClassName, 0, flags,
- 0, 0, 0, 0, m_parentFrame->view()->containingWindow(), 0, Page::instanceHandle(), 0);
-
+ HWND parentWindowHandle = windowHandleForPlatformWidget(m_parentFrame->view()->hostWindow()->platformWindow());
+ HWND window = ::CreateWindowEx(0, kWebPluginViewdowClassName, 0, flags,
+ 0, 0, 0, 0, parentWindowHandle, 0, Page::instanceHandle(), 0);
+#if PLATFORM(WIN_OS) && PLATFORM(QT)
+ m_window = window;
+#else
+ setPlatformWidget(window);
+#endif
+
// Calling SetWindowLongPtrA here makes the window proc ASCII, which is required by at least
// the Shockwave Director plug-in.
- ::SetWindowLongPtrA(m_window, GWL_WNDPROC, (LONG)DefWindowProcA);
-
- SetProp(m_window, kWebPluginViewProperty, this);
+#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC)
+ ::SetWindowLongPtrA(platformPluginWidget(), GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
+#else
+ ::SetWindowLongPtrA(platformPluginWidget(), GWL_WNDPROC, (LONG)DefWindowProcA);
+#endif
+ SetProp(platformPluginWidget(), kWebPluginViewProperty, this);
m_npWindow.type = NPWindowTypeWindow;
- m_npWindow.window = m_window;
+ m_npWindow.window = platformPluginWidget();
} else {
m_npWindow.type = NPWindowTypeDrawable;
m_npWindow.window = 0;
}
- if (!m_quirks.contains(PluginQuirkDeferFirstSetWindowCall))
- setNPWindowRect(frameGeometry());
+ if (!m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall))
+ setNPWindowRect(frameRect());
m_status = PluginStatusLoadedSuccessfully;
}
-void PluginView::didReceiveResponse(const ResourceResponse& response)
-{
- ASSERT(m_loadManually);
- ASSERT(!m_manualStream);
-
- m_manualStream = new PluginStream(this, m_parentFrame, m_parentFrame->loader()->activeDocumentLoader()->request(), false, 0, plugin()->pluginFuncs(), instance(), m_quirks);
- m_manualStream->setLoadManually(true);
-
- m_manualStream->didReceiveResponse(0, response);
-}
-
-void PluginView::didReceiveData(const char* data, int length)
-{
- ASSERT(m_loadManually);
- ASSERT(m_manualStream);
-
- m_manualStream->didReceiveData(0, data, length);
-}
-
-void PluginView::didFinishLoading()
-{
- ASSERT(m_loadManually);
- ASSERT(m_manualStream);
-
- m_manualStream->didFinishLoading(0);
-}
-
-void PluginView::didFail(const ResourceError& error)
-{
- ASSERT(m_loadManually);
- ASSERT(m_manualStream);
-
- m_manualStream->didFail(0, error);
-}
-
-void PluginView::setCallingPlugin(bool b) const
-{
- if (!m_quirks.contains(PluginQuirkHasModalMessageLoop))
- return;
-
- if (b)
- ++s_callingPlugin;
- else
- --s_callingPlugin;
-
- ASSERT(s_callingPlugin >= 0);
-}
-
-bool PluginView::isCallingPlugin()
-{
- return s_callingPlugin > 0;
-}
-
} // namespace WebCore
diff --git a/WebCore/plugins/wx/PluginDataWx.cpp b/WebCore/plugins/wx/PluginDataWx.cpp
new file mode 100644
index 0000000..28e3967
--- /dev/null
+++ b/WebCore/plugins/wx/PluginDataWx.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 Kevin Ollivier <kevino@theolliviers.com> All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "PluginData.h"
+
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+void PluginData::initPlugins()
+{
+ notImplemented();
+}
+
+void PluginData::refresh()
+{
+ notImplemented();
+}
+
+};
diff --git a/WebCore/plugins/wx/PluginPackageWx.cpp b/WebCore/plugins/wx/PluginPackageWx.cpp
new file mode 100644
index 0000000..b93ead2
--- /dev/null
+++ b/WebCore/plugins/wx/PluginPackageWx.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 Kevin Ollivier <kevino@theolliviers.com> All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginPackage.h"
+
+#include "CString.h"
+#include "MIMETypeRegistry.h"
+#include "NotImplemented.h"
+#include "npruntime_impl.h"
+#include "PluginDatabase.h"
+#include "PluginDebug.h"
+
+namespace WebCore {
+
+void PluginPackage::determineQuirks(const String& mimeType)
+{
+ notImplemented();
+}
+
+bool PluginPackage::fetchInfo()
+{
+ notImplemented();
+ return false;
+}
+
+bool PluginPackage::load()
+{
+ notImplemented();
+ return false;
+}
+
+unsigned PluginPackage::hash() const
+{
+ notImplemented();
+
+ return 0;
+}
+
+bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b)
+{
+ notImplemented();
+ return false;
+}
+
+int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const
+{
+ notImplemented();
+ return 0;
+}
+
+}
diff --git a/WebCore/plugins/wx/PluginViewWx.cpp b/WebCore/plugins/wx/PluginViewWx.cpp
new file mode 100644
index 0000000..834761c
--- /dev/null
+++ b/WebCore/plugins/wx/PluginViewWx.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2008 Kevin Ollivier <kevino@theolliviers.com> All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PluginView.h"
+
+#include "NotImplemented.h"
+#include "PluginPackage.h"
+
+using namespace WTF;
+
+namespace WebCore {
+
+void PluginView::setFocus()
+{
+ notImplemented();
+}
+
+void PluginView::show()
+{
+ notImplemented();
+}
+
+void PluginView::hide()
+{
+ notImplemented();
+}
+
+void PluginView::paint(GraphicsContext* context, const IntRect& rect)
+{
+ notImplemented();
+}
+
+void PluginView::handleKeyboardEvent(KeyboardEvent* event)
+{
+ notImplemented();
+}
+
+void PluginView::handleMouseEvent(MouseEvent* event)
+{
+ notImplemented();
+}
+
+void PluginView::setParent(ScrollView* parent)
+{
+ notImplemented();
+}
+
+void PluginView::setNPWindowRect(const IntRect& rect)
+{
+ notImplemented();
+}
+
+void PluginView::stop()
+{
+ notImplemented();
+}
+
+const char* PluginView::userAgent()
+{
+ notImplemented();
+ return 0;
+}
+
+NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf)
+{
+ notImplemented();
+
+ return 0;
+}
+
+NPError PluginView::getValue(NPNVariable variable, void* value)
+{
+ notImplemented();
+ return 0;
+}
+
+void PluginView::invalidateRect(NPRect* rect)
+{
+ notImplemented();
+}
+
+void PluginView::invalidateRect(const IntRect&)
+{
+ notImplemented();
+}
+
+void PluginView::invalidateRegion(NPRegion region)
+{
+ notImplemented();
+}
+
+void PluginView::forceRedraw()
+{
+ notImplemented();
+}
+
+PluginView::~PluginView()
+{
+ notImplemented();
+}
+
+void PluginView::init()
+{
+ notImplemented();
+}
+
+void PluginView::setParentVisible(bool)
+{
+ notImplemented();
+}
+
+void PluginView::updatePluginWidget() const
+{
+ notImplemented();
+}
+
+} // namespace WebCore