diff options
Diffstat (limited to 'Source/WebCore/plugins/win')
-rw-r--r-- | Source/WebCore/plugins/win/PluginDatabaseWin.cpp | 436 | ||||
-rw-r--r-- | Source/WebCore/plugins/win/PluginMessageThrottlerWin.cpp | 151 | ||||
-rw-r--r-- | Source/WebCore/plugins/win/PluginMessageThrottlerWin.h | 74 | ||||
-rw-r--r-- | Source/WebCore/plugins/win/PluginPackageWin.cpp | 345 | ||||
-rw-r--r-- | Source/WebCore/plugins/win/PluginViewWin.cpp | 1081 |
5 files changed, 0 insertions, 2087 deletions
diff --git a/Source/WebCore/plugins/win/PluginDatabaseWin.cpp b/Source/WebCore/plugins/win/PluginDatabaseWin.cpp deleted file mode 100644 index 5cd6d1443..000000000 --- a/Source/WebCore/plugins/win/PluginDatabaseWin.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora, Ltd. All rights reserved. - * Copyright (C) 2008-2009 Torch Mobile, 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 "PluginDatabase.h" - -#include "Frame.h" -#include "URL.h" -#include "PluginPackage.h" -#include <wtf/WindowsExtras.h> - -#if OS(WINCE) -// WINCE doesn't support Registry Key Access Rights. The parameter should always be 0 -#ifndef KEY_ENUMERATE_SUB_KEYS -#define KEY_ENUMERATE_SUB_KEYS 0 -#endif - -BOOL PathRemoveFileSpec(LPWSTR moduleFileNameStr) -{ - if (!*moduleFileNameStr) - return FALSE; - - LPWSTR lastPos = 0; - LPWSTR curPos = moduleFileNameStr; - do { - if (*curPos == L'/' || *curPos == L'\\') - lastPos = curPos; - } while (*++curPos); - - if (lastPos == curPos - 1) - return FALSE; - - if (lastPos) - *lastPos = 0; - else { - moduleFileNameStr[0] = L'\\'; - moduleFileNameStr[1] = 0; - } - - return TRUE; -} -#endif - -namespace WebCore { - -static inline void addPluginPathsFromRegistry(HKEY rootKey, HashSet<String>& paths) -{ - HKEY key; - HRESULT result = RegOpenKeyExW(rootKey, L"Software\\MozillaPlugins", 0, KEY_ENUMERATE_SUB_KEYS, &key); - - if (result != ERROR_SUCCESS) - return; - - wchar_t name[128]; - FILETIME lastModified; - - // Enumerate subkeys - for (int i = 0;; i++) { - DWORD nameLen = WTF_ARRAY_LENGTH(name); - result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified); - - if (result != ERROR_SUCCESS) - break; - - WCHAR pathStr[_MAX_PATH]; - DWORD pathStrSize = sizeof(pathStr); - DWORD type; - - result = getRegistryValue(key, name, L"Path", &type, pathStr, &pathStrSize); - if (result != ERROR_SUCCESS || type != REG_SZ) - continue; - - paths.add(String(pathStr, pathStrSize / sizeof(WCHAR) - 1)); - } - - RegCloseKey(key); -} - -void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const -{ - // FIXME: This should be a case insensitive set. - HashSet<String> uniqueFilenames; - - HANDLE hFind = INVALID_HANDLE_VALUE; - WIN32_FIND_DATAW findFileData; - - String oldWMPPluginPath; - String newWMPPluginPath; - - 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().data(), &findFileData); - - if (hFind == INVALID_HANDLE_VALUE) - continue; - - do { - if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - - String filename = String(findFileData.cFileName, wcslen(findFileData.cFileName)); - if ((!filename.startsWith("np", false) || !filename.endsWith("dll", false)) && - (!equalIgnoringCase(filename, "Plugin.dll") || !it->endsWith("Shockwave 10", false))) - continue; - - String fullPath = *it + "\\" + filename; - if (!uniqueFilenames.add(fullPath).isNewEntry) - continue; - - paths.add(fullPath); - - if (equalIgnoringCase(filename, "npdsplay.dll")) - oldWMPPluginPath = fullPath; - else if (equalIgnoringCase(filename, "np-mswmp.dll")) - newWMPPluginPath = fullPath; - - } while (FindNextFileW(hFind, &findFileData) != 0); - - FindClose(hFind); - } - - 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 (!oldWMPPluginPath.isEmpty() && !newWMPPluginPath.isEmpty()) - paths.remove(oldWMPPluginPath); -} - -static inline Vector<int> parseVersionString(const String& versionString) -{ - Vector<int> version; - - unsigned startPos = 0; - unsigned endPos; - - while (startPos < versionString.length()) { - for (endPos = startPos; endPos < versionString.length(); ++endPos) - if (versionString[endPos] == '.' || versionString[endPos] == '_') - break; - - int versionComponent = versionString.substring(startPos, endPos - startPos).toInt(); - version.append(versionComponent); - - startPos = endPos + 1; - } - - return version; -} - -// This returns whether versionA is higher than versionB -static inline bool compareVersions(const Vector<int>& versionA, const Vector<int>& versionB) -{ - for (unsigned i = 0; i < versionA.size(); i++) { - if (i >= versionB.size()) - return true; - - if (versionA[i] > versionB[i]) - return true; - else if (versionA[i] < versionB[i]) - return false; - } - - // If we come here, the versions are either the same or versionB has an extra component, just return false - return false; -} - -static inline void addMozillaPluginDirectories(Vector<String>& directories) -{ - // Enumerate all Mozilla plugin directories in the registry - HKEY key; - LONG result; - - result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Mozilla"), 0, KEY_READ, &key); - if (result == ERROR_SUCCESS) { - WCHAR name[128]; - FILETIME lastModified; - - // Enumerate subkeys - for (int i = 0;; i++) { - DWORD nameLen = sizeof(name) / sizeof(WCHAR); - result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified); - - if (result != ERROR_SUCCESS) - break; - - String extensionsPath = String(name, nameLen) + "\\Extensions"; - HKEY extensionsKey; - - // Try opening the key - result = RegOpenKeyEx(key, extensionsPath.charactersWithNullTermination().data(), 0, KEY_READ, &extensionsKey); - - if (result == ERROR_SUCCESS) { - // Now get the plugins directory - WCHAR pluginsDirectoryStr[_MAX_PATH]; - DWORD pluginsDirectorySize = sizeof(pluginsDirectoryStr); - DWORD type; - - result = RegQueryValueEx(extensionsKey, TEXT("Plugins"), 0, &type, (LPBYTE)&pluginsDirectoryStr, &pluginsDirectorySize); - - if (result == ERROR_SUCCESS && type == REG_SZ) - directories.append(String(pluginsDirectoryStr, pluginsDirectorySize / sizeof(WCHAR) - 1)); - - RegCloseKey(extensionsKey); - } - } - - RegCloseKey(key); - } -} - -static inline void addWindowsMediaPlayerPluginDirectory(Vector<String>& directories) -{ -#if !OS(WINCE) - // 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, WTF_ARRAY_LENGTH(pluginDirectoryStr)); - - if (pluginDirectorySize > 0 && pluginDirectorySize <= WTF_ARRAY_LENGTH(pluginDirectoryStr)) - directories.append(String(pluginDirectoryStr, pluginDirectorySize - 1)); -#endif - - DWORD type; - WCHAR installationDirectoryStr[_MAX_PATH]; - DWORD installationDirectorySize = sizeof(installationDirectoryStr); - - HRESULT result = getRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MediaPlayer", L"Installation Directory", &type, &installationDirectoryStr, &installationDirectorySize); - - if (result == ERROR_SUCCESS && type == REG_SZ) - directories.append(String(installationDirectoryStr, installationDirectorySize / sizeof(WCHAR) - 1)); -} - -static inline void addQuickTimePluginDirectory(Vector<String>& directories) -{ - DWORD type; - WCHAR installationDirectoryStr[_MAX_PATH]; - DWORD installationDirectorySize = sizeof(installationDirectoryStr); - - HRESULT result = getRegistryValue(HKEY_LOCAL_MACHINE, L"Software\\Apple Computer, Inc.\\QuickTime", L"InstallDir", &type, &installationDirectoryStr, &installationDirectorySize); - - if (result == ERROR_SUCCESS && type == REG_SZ) { - String pluginDir = String(installationDirectoryStr, installationDirectorySize / sizeof(WCHAR) - 1) + "\\plugins"; - directories.append(pluginDir); - } -} - -static inline void addAdobeAcrobatPluginDirectory(Vector<String>& directories) -{ - HKEY key; - HRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Adobe\\Acrobat Reader"), 0, KEY_READ, &key); - if (result != ERROR_SUCCESS) - return; - - WCHAR name[128]; - FILETIME lastModified; - - Vector<int> latestAcrobatVersion; - String latestAcrobatVersionString; - - // Enumerate subkeys - for (int i = 0;; i++) { - DWORD nameLen = sizeof(name) / sizeof(WCHAR); - result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified); - - if (result != ERROR_SUCCESS) - break; - - Vector<int> acrobatVersion = parseVersionString(String(name, nameLen)); - if (compareVersions(acrobatVersion, latestAcrobatVersion)) { - latestAcrobatVersion = acrobatVersion; - latestAcrobatVersionString = String(name, nameLen); - } - } - - if (!latestAcrobatVersionString.isNull()) { - DWORD type; - WCHAR acrobatInstallPathStr[_MAX_PATH]; - DWORD acrobatInstallPathSize = sizeof(acrobatInstallPathStr); - - String acrobatPluginKeyPath = "Software\\Adobe\\Acrobat Reader\\" + latestAcrobatVersionString + "\\InstallPath"; - result = getRegistryValue(HKEY_LOCAL_MACHINE, acrobatPluginKeyPath.charactersWithNullTermination().data(), 0, &type, acrobatInstallPathStr, &acrobatInstallPathSize); - - if (result == ERROR_SUCCESS) { - String acrobatPluginDirectory = String(acrobatInstallPathStr, acrobatInstallPathSize / sizeof(WCHAR) - 1) + "\\browser"; - directories.append(acrobatPluginDirectory); - } - } - - RegCloseKey(key); -} - -static inline void addJavaPluginDirectory(Vector<String>& directories) -{ - HKEY key; - HRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\JavaSoft\\Java Plug-in"), 0, KEY_READ, &key); - if (result != ERROR_SUCCESS) - return; - - WCHAR name[128]; - FILETIME lastModified; - - Vector<int> latestJavaVersion; - String latestJavaVersionString; - - // Enumerate subkeys - for (int i = 0;; i++) { - DWORD nameLen = sizeof(name) / sizeof(WCHAR); - result = RegEnumKeyExW(key, i, name, &nameLen, 0, 0, 0, &lastModified); - - if (result != ERROR_SUCCESS) - break; - - Vector<int> javaVersion = parseVersionString(String(name, nameLen)); - if (compareVersions(javaVersion, latestJavaVersion)) { - latestJavaVersion = javaVersion; - latestJavaVersionString = String(name, nameLen); - } - } - - if (!latestJavaVersionString.isEmpty()) { - DWORD type; - WCHAR javaInstallPathStr[_MAX_PATH]; - DWORD javaInstallPathSize = sizeof(javaInstallPathStr); - DWORD useNewPluginValue; - DWORD useNewPluginSize; - - String javaPluginKeyPath = "Software\\JavaSoft\\Java Plug-in\\" + latestJavaVersionString; - result = getRegistryValue(HKEY_LOCAL_MACHINE, javaPluginKeyPath.charactersWithNullTermination().data(), L"UseNewJavaPlugin", &type, &useNewPluginValue, &useNewPluginSize); - - if (result == ERROR_SUCCESS && useNewPluginValue == 1) { - result = getRegistryValue(HKEY_LOCAL_MACHINE, javaPluginKeyPath.charactersWithNullTermination().data(), L"JavaHome", &type, javaInstallPathStr, &javaInstallPathSize); - if (result == ERROR_SUCCESS) { - String javaPluginDirectory = String(javaInstallPathStr, javaInstallPathSize / sizeof(WCHAR) - 1) + "\\bin\\new_plugin"; - directories.append(javaPluginDirectory); - } - } - } - - RegCloseKey(key); -} - -static inline String safariPluginsDirectory() -{ - WCHAR moduleFileNameStr[_MAX_PATH]; - static String pluginsDirectory; - static bool cachedPluginDirectory = false; - - if (!cachedPluginDirectory) { - cachedPluginDirectory = true; - - int moduleFileNameLen = GetModuleFileName(0, moduleFileNameStr, _MAX_PATH); - - if (!moduleFileNameLen || moduleFileNameLen == _MAX_PATH) - goto exit; - - if (!PathRemoveFileSpec(moduleFileNameStr)) - goto exit; - - pluginsDirectory = String(moduleFileNameStr) + "\\Plugins"; - } -exit: - return pluginsDirectory; -} - -static inline void addMacromediaPluginDirectories(Vector<String>& directories) -{ -#if !OS(WINCE) - WCHAR systemDirectoryStr[MAX_PATH]; - - if (!GetSystemDirectory(systemDirectoryStr, WTF_ARRAY_LENGTH(systemDirectoryStr))) - return; - - WCHAR macromediaDirectoryStr[MAX_PATH]; - - PathCombine(macromediaDirectoryStr, systemDirectoryStr, TEXT("macromed\\Flash")); - directories.append(macromediaDirectoryStr); - - PathCombine(macromediaDirectoryStr, systemDirectoryStr, TEXT("macromed\\Shockwave 10")); - directories.append(macromediaDirectoryStr); -#endif -} - -Vector<String> PluginDatabase::defaultPluginDirectories() -{ - 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::isPreferredPluginDirectory(const String& directory) -{ - String ourDirectory = safariPluginsDirectory(); - - if (!ourDirectory.isNull() && !directory.isNull()) - return ourDirectory == directory; - - return false; -} - -} diff --git a/Source/WebCore/plugins/win/PluginMessageThrottlerWin.cpp b/Source/WebCore/plugins/win/PluginMessageThrottlerWin.cpp deleted file mode 100644 index b32728980..000000000 --- a/Source/WebCore/plugins/win/PluginMessageThrottlerWin.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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> -#include <wtf/CurrentTime.h> - -using namespace WTF; - -namespace WebCore { - -// Set a timer to make sure we process any queued messages at least every 16ms. -// This value allows Flash 60 messages/second, which should be enough for video -// playback, and also gets us over the limit for kicking into high-resolution -// timer mode (see SharedTimerWin.cpp). -static const double MessageThrottleTimeInterval = 0.016; - -// During a continuous stream of messages, process one every 5ms. -static const double MessageDirectProcessingInterval = 0.005; - -PluginMessageThrottlerWin::PluginMessageThrottlerWin(PluginView* pluginView) - : m_pluginView(pluginView) - , m_back(0) - , m_front(0) - , m_messageThrottleTimer(this, &PluginMessageThrottlerWin::messageThrottleTimerFired) - , m_lastMessageTime(0) -{ - // 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 it has been more than MessageDirectProcessingInterval between throttled messages, - // go ahead and process a message directly. - double currentTime = monotonicallyIncreasingTime(); - if (currentTime - m_lastMessageTime > MessageDirectProcessingInterval) { - processQueuedMessage(); - m_lastMessageTime = currentTime; - if (!m_front) - return; - } - - if (!m_messageThrottleTimer.isActive()) - m_messageThrottleTimer.startOneShot(MessageThrottleTimeInterval); -} - -void PluginMessageThrottlerWin::processQueuedMessage() -{ - PluginMessage* message = m_front; - m_front = m_front->next; - if (message == m_back) - m_back = 0; - - // Protect the PluginView from destruction while calling its window proc. - // <rdar://problem/6930280> - RefPtr<PluginView> protect(m_pluginView); - ::CallWindowProc(m_pluginView->pluginWndProc(), message->hWnd, message->msg, message->wParam, message->lParam); - - freeMessage(message); -} - -void PluginMessageThrottlerWin::messageThrottleTimerFired(Timer<PluginMessageThrottlerWin>*) -{ - processQueuedMessage(); - - 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/Source/WebCore/plugins/win/PluginMessageThrottlerWin.h b/Source/WebCore/plugins/win/PluginMessageThrottlerWin.h deleted file mode 100644 index 0a7be70ca..000000000 --- a/Source/WebCore/plugins/win/PluginMessageThrottlerWin.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 processQueuedMessage(); - 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; - double m_lastMessageTime; - }; - -} // namespace WebCore - -#endif // PluginMessageThrottlerWin_h diff --git a/Source/WebCore/plugins/win/PluginPackageWin.cpp b/Source/WebCore/plugins/win/PluginPackageWin.cpp deleted file mode 100644 index 2270190f0..000000000 --- a/Source/WebCore/plugins/win/PluginPackageWin.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora, Ltd. All rights reserved. - * Copyright (C) 2009 Torch Mobile, 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 "MIMETypeRegistry.h" -#include "PluginDatabase.h" -#include "PluginDebug.h" -#include "Timer.h" -#include "npruntime_impl.h" -#include <string.h> -#include <wtf/StdLibExtras.h> -#include <wtf/text/CString.h> -#include <shlwapi.h> - -namespace WebCore { - -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().data()), - &buffer, &bufferLength); - if (!retval || bufferLength == 0) - return String(); - - // Subtract 1 from the length; we don't want the trailing null character. - return String(reinterpret_cast<UChar*>(buffer), bufferLength - 1); -} - -bool PluginPackage::isPluginBlacklisted() -{ - if (name() == "Citrix ICA Client") { - // The Citrix ICA Client plug-in requires a Mozilla-based browser; see <rdar://6418681>. - return true; - } - - 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 - static const PlatformModuleVersion slPluginMinRequired(0x51BE0000, 0x00010000); - - if (compareFileVersion(slPluginMinRequired) < 0) - return true; - } else if (equalIgnoringCase(fileName(), "npmozax.dll")) { - // Bug 15217: Mozilla ActiveX control complains about missing xpcom_core.dll - return true; - } else if (equalIgnoringCase(fileName(), "npwpf.dll")) { - // Bug 57119: Microsoft Windows Presentation Foundation (WPF) plug-in complains about missing xpcom.dll - return true; - } else if (name() == "Yahoo Application State Plugin") { - // https://bugs.webkit.org/show_bug.cgi?id=26860 - // Bug in Yahoo Application State plug-in earlier than 1.0.0.6 leads to heap corruption. - static const PlatformModuleVersion yahooAppStatePluginMinRequired(0x00000006, 0x00010000); - if (compareFileVersion(yahooAppStatePluginMinRequired) < 0) - return true; - } - - 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" || name() == "VLC Multimedia Plug-in") { - // 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(const_cast<UChar*>(m_path.charactersWithNullTermination().data()), &zeroHandle); - if (versionInfoSize == 0) - return false; - - auto versionInfoData = std::make_unique<char[]>(versionInfoSize); - - if (!GetFileVersionInfoW(const_cast<UChar*>(m_path.charactersWithNullTermination().data()), - 0, versionInfoSize, versionInfoData.get())) - return false; - - m_name = getVersionInfo(versionInfoData.get(), "ProductName"); - m_description = getVersionInfo(versionInfoData.get(), "FileDescription"); - if (m_name.isNull() || m_description.isNull()) - return false; - - VS_FIXEDFILEINFO* info; - UINT infoSize; - if (!VerQueryValueW(versionInfoData.get(), L"\\", (LPVOID*) &info, &infoSize) || infoSize < sizeof(VS_FIXEDFILEINFO)) - return false; - m_moduleVersion.leastSig = info->dwFileVersionLS; - m_moduleVersion.mostSig = info->dwFileVersionMS; - - if (isPluginBlacklisted()) - return false; - - 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] : ""; - - Vector<String> extensionsVector; - extensionList.split(',', extensionsVector); - - // 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. - if (pos > 1 && description[pos - 1] == ' ') - pos--; - description = description.left(pos); - } - - // Determine the quirks for the MIME types this plug-in supports - determineQuirks(type); - - m_mimeToExtensions.add(type, extensionsVector); - m_mimeToDescriptions.add(type, description); - } - - return true; -} - -bool PluginPackage::load() -{ - if (m_freeLibraryTimer.isActive()) { - ASSERT(m_module); - m_freeLibraryTimer.stop(); - } else if (m_isLoaded) { - if (m_quirks.contains(PluginQuirkDontAllowMultipleInstances)) - return false; - m_loadCount++; - return true; - } else { -#if OS(WINCE) - m_module = ::LoadLibraryW(m_path.charactersWithNullTermination().data()); -#else - WCHAR currentPath[MAX_PATH]; - - if (!::GetCurrentDirectoryW(MAX_PATH, currentPath)) - return false; - - String path = m_path.substring(0, m_path.reverseFind('\\')); - - if (!::SetCurrentDirectoryW(path.charactersWithNullTermination().data())) - return false; - - // Load the library - m_module = ::LoadLibraryExW(m_path.charactersWithNullTermination().data(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); - - if (!::SetCurrentDirectoryW(currentPath)) { - if (m_module) - ::FreeLibrary(m_module); - return false; - } -#endif - } - - if (!m_module) - return false; - - m_isLoaded = true; - - NP_GetEntryPointsFuncPtr NP_GetEntryPoints = 0; - NP_InitializeFuncPtr NP_Initialize = 0; - NPError npErr; - -#if OS(WINCE) - NP_Initialize = (NP_InitializeFuncPtr)GetProcAddress(m_module, L"NP_Initialize"); - NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)GetProcAddress(m_module, L"NP_GetEntryPoints"); - m_NPP_Shutdown = (NPP_ShutdownProcPtr)GetProcAddress(m_module, L"NP_Shutdown"); -#else - NP_Initialize = (NP_InitializeFuncPtr)GetProcAddress(m_module, "NP_Initialize"); - NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)GetProcAddress(m_module, "NP_GetEntryPoints"); - m_NPP_Shutdown = (NPP_ShutdownProcPtr)GetProcAddress(m_module, "NP_Shutdown"); -#endif - - if (!NP_Initialize || !NP_GetEntryPoints || !m_NPP_Shutdown) - goto abort; - - memset(&m_pluginFuncs, 0, sizeof(m_pluginFuncs)); - m_pluginFuncs.size = sizeof(m_pluginFuncs); - - npErr = NP_GetEntryPoints(&m_pluginFuncs); - LOG_NPERROR(npErr); - if (npErr != NPERR_NO_ERROR) - goto abort; - - initializeBrowserFuncs(); - - npErr = NP_Initialize(&m_browserFuncs); - LOG_NPERROR(npErr); - - if (npErr != NPERR_NO_ERROR) - goto abort; - - m_loadCount++; - return true; - -abort: - unloadWithoutShutdown(); - return false; -} - -unsigned PluginPackage::hash() const -{ - const unsigned hashCodes[] = { - m_name.impl()->hash(), - m_description.impl()->hash(), - m_mimeToExtensions.size() - }; - - return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes); -} - -bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b) -{ - 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; -} - -uint16_t PluginPackage::NPVersion() const -{ - return NP_VERSION_MINOR; -} -} diff --git a/Source/WebCore/plugins/win/PluginViewWin.cpp b/Source/WebCore/plugins/win/PluginViewWin.cpp deleted file mode 100644 index fa3ad1855..000000000 --- a/Source/WebCore/plugins/win/PluginViewWin.cpp +++ /dev/null @@ -1,1081 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2013 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora Ltd. All rights reserved. - * Copyright (C) 2008-2009 Torch Mobile, 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 "PluginView.h" - -#include "BitmapImage.h" -#include "BitmapInfo.h" -#include "BridgeJSC.h" -#include "Chrome.h" -#include "ChromeClient.h" -#include "Document.h" -#include "DocumentLoader.h" -#include "Element.h" -#include "EventNames.h" -#include "FocusController.h" -#include "Frame.h" -#include "FrameLoadRequest.h" -#include "FrameLoader.h" -#include "FrameTree.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "HTMLNames.h" -#include "HTMLPlugInElement.h" -#include "HostWindow.h" -#include "Image.h" -#include "JSDOMBinding.h" -#include "JSDOMWindow.h" -#include "KeyboardEvent.h" -#include "LocalWindowsContext.h" -#include "MIMETypeRegistry.h" -#include "MouseEvent.h" -#include "Page.h" -#include "PlatformMouseEvent.h" -#include "PluginDatabase.h" -#include "PluginDebug.h" -#include "PluginMainThreadScheduler.h" -#include "PluginMessageThrottlerWin.h" -#include "PluginPackage.h" -#include "RenderWidget.h" -#include "Settings.h" -#include "WebCoreInstanceHandle.h" -#include "c_instance.h" -#include "npruntime_impl.h" -#include "runtime_root.h" -#include <runtime/JSCJSValue.h> -#include <runtime/JSLock.h> -#include <wtf/ASCIICType.h> -#include <wtf/text/WTFString.h> -#include <wtf/win/GDIObject.h> - -#if OS(WINCE) -#undef LOG_NPERROR -#define LOG_NPERROR(x) -#undef LOG_PLUGIN_NET_ERROR -#define LOG_PLUGIN_NET_ERROR() -#endif - -#if USE(CAIRO) -#include "PlatformContextCairo.h" -#include <cairo-win32.h> -#endif - -#if PLATFORM(GTK) -#include <gdk/gdkwin32.h> -#include <gtk/gtk.h> -#endif - -static inline HWND windowHandleForPageClient(PlatformPageClient client) -{ -#if PLATFORM(GTK) - if (!client) - return 0; - if (GdkWindow* window = gtk_widget_get_window(client)) - return static_cast<HWND>(GDK_WINDOW_HWND(window)); - return 0; -#else - return client; -#endif -} - -using JSC::ExecState; -using JSC::JSLock; -using JSC::JSObject; - -using std::min; - -using namespace WTF; - -namespace WebCore { - -using namespace HTMLNames; - -const LPCWSTR kWebPluginViewdowClassName = L"WebPluginView"; -const LPCWSTR kWebPluginViewProperty = L"WebPluginViewProperty"; - -#if !OS(WINCE) -// The code used to hook BeginPaint/EndPaint originally came from -// <http://www.fengyuan.com/article/wmprint.html>. -// Copyright (C) 2000 by Feng Yuan (www.fengyuan.com). - -static unsigned beginPaintSysCall; -static BYTE* beginPaint; - -static unsigned endPaintSysCall; -static BYTE* endPaint; - -typedef HDC (WINAPI *PtrBeginPaint)(HWND, PAINTSTRUCT*); -typedef BOOL (WINAPI *PtrEndPaint)(HWND, const PAINTSTRUCT*); - -#if OS(WINDOWS) && CPU(X86_64) && COMPILER(MSVC) -extern "C" HDC __stdcall _HBeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); -extern "C" BOOL __stdcall _HEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint); -#endif - -HDC WINAPI PluginView::hookedBeginPaint(HWND hWnd, PAINTSTRUCT* lpPaint) -{ - PluginView* pluginView = reinterpret_cast<PluginView*>(GetProp(hWnd, kWebPluginViewProperty)); - if (pluginView && pluginView->m_wmPrintHDC) { - // We're secretly handling WM_PRINTCLIENT, so set up the PAINTSTRUCT so - // that the plugin will paint into the HDC we provide. - memset(lpPaint, 0, sizeof(PAINTSTRUCT)); - lpPaint->hdc = pluginView->m_wmPrintHDC; - GetClientRect(hWnd, &lpPaint->rcPaint); - return pluginView->m_wmPrintHDC; - } - -#if COMPILER(GCC) - HDC result; - asm ("push %2\n" - "push %3\n" - "call *%4\n" - : "=a" (result) - : "a" (beginPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (beginPaint) - : "memory" - ); - return result; -#elif defined(_M_IX86) - // Call through to the original BeginPaint. - __asm mov eax, beginPaintSysCall - __asm push lpPaint - __asm push hWnd - __asm call beginPaint -#else - return _HBeginPaint(hWnd, lpPaint); -#endif -} - -BOOL WINAPI PluginView::hookedEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint) -{ - PluginView* pluginView = reinterpret_cast<PluginView*>(GetProp(hWnd, kWebPluginViewProperty)); - if (pluginView && pluginView->m_wmPrintHDC) { - // We're secretly handling WM_PRINTCLIENT, so we don't have to do any - // cleanup. - return TRUE; - } - -#if COMPILER(GCC) - BOOL result; - asm ("push %2\n" - "push %3\n" - "call *%4\n" - : "=a" (result) - : "a" (endPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (endPaint) - ); - return result; -#elif defined (_M_IX86) - // Call through to the original EndPaint. - __asm mov eax, endPaintSysCall - __asm push lpPaint - __asm push hWnd - __asm call endPaint -#else - return _HEndPaint(hWnd, lpPaint); -#endif -} - -static void hook(const char* module, const char* proc, unsigned& sysCallID, BYTE*& pProc, const void* pNewProc) -{ - // See <http://www.fengyuan.com/article/wmprint.html> for an explanation of - // how this function works. - - HINSTANCE hMod = GetModuleHandleA(module); - - pProc = reinterpret_cast<BYTE*>(reinterpret_cast<ptrdiff_t>(GetProcAddress(hMod, proc))); - -#if COMPILER(GCC) || defined(_M_IX86) - if (pProc[0] != 0xB8) - return; - - // FIXME: Should we be reading the bytes one-by-one instead of doing an - // unaligned read? - sysCallID = *reinterpret_cast<unsigned*>(pProc + 1); - - DWORD flOldProtect; - if (!VirtualProtect(pProc, 5, PAGE_EXECUTE_READWRITE, &flOldProtect)) - return; - - pProc[0] = 0xE9; - *reinterpret_cast<unsigned*>(pProc + 1) = reinterpret_cast<intptr_t>(pNewProc) - reinterpret_cast<intptr_t>(pProc + 5); - - pProc += 5; -#else - /* Disassembly of BeginPaint() - 00000000779FC5B0 4C 8B D1 mov r10,rcx - 00000000779FC5B3 B8 17 10 00 00 mov eax,1017h - 00000000779FC5B8 0F 05 syscall - 00000000779FC5BA C3 ret - 00000000779FC5BB 90 nop - 00000000779FC5BC 90 nop - 00000000779FC5BD 90 nop - 00000000779FC5BE 90 nop - 00000000779FC5BF 90 nop - 00000000779FC5C0 90 nop - 00000000779FC5C1 90 nop - 00000000779FC5C2 90 nop - 00000000779FC5C3 90 nop - */ - // Check for the signature as in the above disassembly - DWORD guard = 0xB8D18B4C; - if (*reinterpret_cast<DWORD*>(pProc) != guard) - return; - - DWORD flOldProtect; - VirtualProtect(pProc, 12, PAGE_EXECUTE_READWRITE, & flOldProtect); - pProc[0] = 0x48; // mov rax, this - pProc[1] = 0xb8; - *(__int64*)(pProc+2) = (__int64)pNewProc; - pProc[10] = 0xff; // jmp rax - pProc[11] = 0xe0; -#endif -} - -static void setUpOffscreenPaintingHooks(HDC (WINAPI*hookedBeginPaint)(HWND, PAINTSTRUCT*), BOOL (WINAPI*hookedEndPaint)(HWND, const PAINTSTRUCT*)) -{ - static bool haveHooked = false; - if (haveHooked) - return; - haveHooked = true; - - // Most (all?) windowed plugins don't seem to respond to WM_PRINTCLIENT, so - // we hook into BeginPaint/EndPaint to allow their normal WM_PAINT handling - // to draw into a given HDC. Note that this hooking affects the entire - // process. - hook("user32.dll", "BeginPaint", beginPaintSysCall, beginPaint, reinterpret_cast<const void *>(reinterpret_cast<ptrdiff_t>(hookedBeginPaint))); - hook("user32.dll", "EndPaint", endPaintSysCall, endPaint, reinterpret_cast<const void *>(reinterpret_cast<ptrdiff_t>(hookedEndPaint))); - -} -#endif - -static bool registerPluginView() -{ - static bool haveRegisteredWindowClass = false; - if (haveRegisteredWindowClass) - return true; - - haveRegisteredWindowClass = true; - -#if PLATFORM(GTK) - WebCore::setInstanceHandle((HINSTANCE)(GetModuleHandle(0))); -#endif - - ASSERT(WebCore::instanceHandle()); - -#if OS(WINCE) - WNDCLASS wcex = { 0 }; -#else - WNDCLASSEX wcex; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.hIconSm = 0; -#endif - - wcex.style = CS_DBLCLKS; -#if OS(WINCE) - wcex.style |= CS_PARENTDC; -#endif - wcex.lpfnWndProc = DefWindowProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = WebCore::instanceHandle(); - wcex.hIcon = 0; - wcex.hCursor = LoadCursor(0, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)COLOR_WINDOW; - wcex.lpszMenuName = 0; - wcex.lpszClassName = kWebPluginViewdowClassName; - -#if OS(WINCE) - return !!RegisterClass(&wcex); -#else - return !!RegisterClassEx(&wcex); -#endif -} - -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); -} - -static bool isWindowsMessageUserGesture(UINT message) -{ - switch (message) { - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_KEYUP: - return true; - default: - return false; - } -} - -static inline IntPoint contentsToNativeWindow(FrameView* view, const IntPoint& point) -{ - return view->contentsToWindow(point); -} - -static inline IntRect contentsToNativeWindow(FrameView* view, const IntRect& rect) -{ - return view->contentsToWindow(rect); -} - -LRESULT -PluginView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - // <rdar://5711136> Sometimes Flash will call SetCapture before creating - // a full-screen window and will not release it, which causes the - // full-screen window to never receive mouse events. We set/release capture - // on mouse down/up before sending the event to the plug-in to prevent that. - switch (message) { - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - ::SetCapture(hWnd); - break; - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - ::ReleaseCapture(); - break; - } - - if (message == m_lastMessage && - m_plugin->quirks().contains(PluginQuirkDontCallWndProcForSameMessageRecursively) && - m_isCallingPluginWndProc) - return 1; - - if (message == WM_USER + 1 && - m_plugin->quirks().contains(PluginQuirkThrottleWMUserPlusOneMessages)) { - if (!m_messageThrottler) - m_messageThrottler = adoptPtr(new PluginMessageThrottlerWin(this)); - - m_messageThrottler->appendMessage(hWnd, message, wParam, lParam); - return 0; - } - - m_lastMessage = message; - m_isCallingPluginWndProc = true; - - // If the plug-in doesn't explicitly support changing the pop-up state, we enable - // popups for all user gestures. - // Note that we need to pop the state in a timer, because the Flash plug-in - // 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); - } - -#if !OS(WINCE) - if (message == WM_PRINTCLIENT) { - // Most (all?) windowed plugins don't respond to WM_PRINTCLIENT, so we - // change the message to WM_PAINT and rely on our hooked versions of - // BeginPaint/EndPaint to make the plugin draw into the given HDC. - message = WM_PAINT; - m_wmPrintHDC = reinterpret_cast<HDC>(wParam); - } -#endif - - // Call the plug-in's window proc. - LRESULT result = ::CallWindowProc(m_pluginWndProc, hWnd, message, wParam, lParam); - - m_wmPrintHDC = 0; - - m_isCallingPluginWndProc = false; - - return result; -} - -void PluginView::updatePluginWidget() -{ - if (!parent()) - return; - - ASSERT(parent()->isFrameView()); - FrameView* frameView = toFrameView(parent()); - - IntRect oldWindowRect = m_windowRect; - IntRect oldClipRect = m_clipRect; - -#if OS(WINCE) - m_windowRect = frameView->contentsToWindow(frameRect()); -#else - m_windowRect = IntRect(frameView->contentsToWindow(frameRect().location()), frameRect().size()); -#endif - m_clipRect = windowClipRect(); - m_clipRect.move(-m_windowRect.x(), -m_windowRect.y()); - - if (platformPluginWidget() && (!m_haveUpdatedPluginWidget || m_windowRect != oldWindowRect || m_clipRect != oldClipRect)) { - - setCallingPlugin(true); - - // To prevent flashes while scrolling, we disable drawing during the window - // update process by clipping the window to the zero rect. - - bool clipToZeroRect = !m_plugin->quirks().contains(PluginQuirkDontClipToZeroRectWhenScrolling); - - if (clipToZeroRect) { - auto rgn = adoptGDIObject(::CreateRectRgn(0, 0, 0, 0)); - ::SetWindowRgn(platformPluginWidget(), rgn.leak(), FALSE); - } else { - auto rgn = adoptGDIObject(::CreateRectRgn(m_clipRect.x(), m_clipRect.y(), m_clipRect.maxX(), m_clipRect.maxY())); - ::SetWindowRgn(platformPluginWidget(), rgn.leak(), TRUE); - } - - if (!m_haveUpdatedPluginWidget || m_windowRect != oldWindowRect) - ::MoveWindow(platformPluginWidget(), m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), TRUE); - - if (clipToZeroRect) { - auto rgn = adoptGDIObject(::CreateRectRgn(m_clipRect.x(), m_clipRect.y(), m_clipRect.maxX(), m_clipRect.maxY())); - ::SetWindowRgn(platformPluginWidget(), rgn.leak(), TRUE); - } - - setCallingPlugin(false); - - m_haveUpdatedPluginWidget = true; - } -} - -void PluginView::setFocus(bool focused) -{ - if (focused && platformPluginWidget()) - SetFocus(platformPluginWidget()); - - Widget::setFocus(focused); - - if (!m_plugin || m_isWindowed) - return; - - NPEvent npEvent; - - npEvent.event = focused ? WM_SETFOCUS : WM_KILLFOCUS; - npEvent.wParam = 0; - npEvent.lParam = 0; - - dispatchNPEvent(npEvent); -} - -void PluginView::show() -{ - setSelfVisible(true); - - if (isParentVisible() && platformPluginWidget()) - ShowWindow(platformPluginWidget(), SW_SHOWNA); - - Widget::show(); -} - -void PluginView::hide() -{ - setSelfVisible(false); - - if (isParentVisible() && platformPluginWidget()) - ShowWindow(platformPluginWidget(), SW_HIDE); - - Widget::hide(); -} - -bool PluginView::dispatchNPEvent(NPEvent& npEvent) -{ - if (!m_plugin->pluginFuncs()->event) - return true; - - bool shouldPop = false; - - if (m_plugin->pluginFuncs()->version < NPVERS_HAS_POPUPS_ENABLED_STATE && isWindowsMessageUserGesture(npEvent.event)) { - pushPopupsEnabledState(true); - shouldPop = true; - } - - JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); - setCallingPlugin(true); - bool accepted = !m_plugin->pluginFuncs()->event(m_instance, &npEvent); - setCallingPlugin(false); - - if (shouldPop) - popPopupsEnabledState(); - - return accepted; -} - -void PluginView::paintIntoTransformedContext(HDC hdc) -{ - if (m_isWindowed) { -#if !OS(WINCE) - SendMessage(platformPluginWidget(), WM_PRINTCLIENT, reinterpret_cast<WPARAM>(hdc), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED); -#endif - return; - } - - m_npWindow.type = NPWindowTypeDrawable; - m_npWindow.window = hdc; - - WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 }; - - IntRect r = contentsToNativeWindow(toFrameView(parent()), frameRect()); - - windowpos.x = r.x(); - windowpos.y = r.y(); - windowpos.cx = r.width(); - windowpos.cy = r.height(); - - NPEvent npEvent; - npEvent.event = WM_WINDOWPOSCHANGED; - npEvent.lParam = reinterpret_cast<uintptr_t>(&windowpos); - npEvent.wParam = 0; - - dispatchNPEvent(npEvent); - - setNPWindowRect(frameRect()); - - npEvent.event = WM_PAINT; - npEvent.wParam = reinterpret_cast<uintptr_t>(hdc); - - // This is supposed to be a pointer to the dirty rect, but it seems that the Flash plugin - // ignores it so we just pass null. - npEvent.lParam = 0; - - dispatchNPEvent(npEvent); -} - -void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const IntRect& rect) -{ -#if !USE(WINGDI) - ASSERT(m_isWindowed); - ASSERT(context->shouldIncludeChildWindows()); - - ASSERT(parent()->isFrameView()); - IntPoint locationInWindow = toFrameView(parent())->convertToContainingWindow(frameRect().location()); - - LocalWindowsContext windowsContext(context, frameRect(), false); - -#if USE(CAIRO) - // Must flush drawings up to this point to the backing metafile, otherwise the - // plugin region will be overwritten with any clear regions specified in the - // cairo-controlled portions of the rendering. - cairo_show_page(context->platformContext()->cr()); -#endif - - HDC hdc = windowsContext.hdc(); - XFORM originalTransform; - GetWorldTransform(hdc, &originalTransform); - - // The plugin expects the DC to be in client coordinates, so we translate - // the DC to make that so. - AffineTransform ctm = context->getCTM(); - ctm.translate(locationInWindow.x(), locationInWindow.y()); - XFORM transform = static_cast<XFORM>(ctm.toTransformationMatrix()); - - SetWorldTransform(hdc, &transform); - - paintIntoTransformedContext(hdc); - - SetWorldTransform(hdc, &originalTransform); -#endif -} - -void PluginView::paint(GraphicsContext* context, const IntRect& rect) -{ - if (!m_isStarted) { - // Draw the "missing plugin" image - paintMissingPluginIcon(context, rect); - return; - } - - if (context->paintingDisabled()) - return; - - // Ensure that we have called SetWindow before we try to paint. - if (!m_haveCalledSetWindow) - setNPWindowRect(frameRect()); - - if (m_isWindowed) { -#if !USE(WINGDI) - if (context->shouldIncludeChildWindows()) - paintWindowedPluginIntoContext(context, rect); -#endif - return; - } - - ASSERT(parent()->isFrameView()); - - // In the GTK and Qt ports we draw in an offscreen buffer and don't want to use the window - // coordinates. -#if PLATFORM(GTK) - IntRect rectInWindow(rect); - rectInWindow.intersect(frameRect()); -#else - IntRect rectInWindow = toFrameView(parent())->contentsToWindow(frameRect()); -#endif - LocalWindowsContext windowsContext(context, rectInWindow, m_isTransparent); - - // 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 GTK and Qt ports we always draw in an offscreen buffer and therefore need - // to preserve the translation set in getWindowsContext. -#if !PLATFORM(GTK) && !OS(WINCE) - if (!context->isInTransparencyLayer()) { - XFORM transform; - GetWorldTransform(windowsContext.hdc(), &transform); - transform.eDx = 0; - transform.eDy = 0; - SetWorldTransform(windowsContext.hdc(), &transform); - } -#endif - - paintIntoTransformedContext(windowsContext.hdc()); -} - -void PluginView::handleKeyboardEvent(KeyboardEvent* event) -{ - ASSERT(m_plugin && !m_isWindowed); - - NPEvent npEvent; - - npEvent.wParam = event->keyCode(); - - if (event->type() == eventNames().keydownEvent) { - npEvent.event = WM_KEYDOWN; - npEvent.lParam = 0; - } else if (event->type() == eventNames().keypressEvent) { - npEvent.event = WM_CHAR; - npEvent.lParam = 0; - } else if (event->type() == eventNames().keyupEvent) { - npEvent.event = WM_KEYUP; - npEvent.lParam = 0x8000; - } else - return; - - JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); - if (dispatchNPEvent(npEvent)) - event->setDefaultHandled(); -} - -#if !OS(WINCE) -extern bool ignoreNextSetCursor; -#endif - -void PluginView::handleMouseEvent(MouseEvent* event) -{ - ASSERT(m_plugin && !m_isWindowed); - - NPEvent npEvent; - - IntPoint p = contentsToNativeWindow(toFrameView(parent()), IntPoint(event->pageX(), event->pageY())); - - npEvent.lParam = MAKELPARAM(p.x(), p.y()); - npEvent.wParam = 0; - - if (event->ctrlKey()) - npEvent.wParam |= MK_CONTROL; - if (event->shiftKey()) - npEvent.wParam |= MK_SHIFT; - - if (event->type() == eventNames().mousemoveEvent || - event->type() == eventNames().mouseoutEvent || - event->type() == eventNames().mouseoverEvent) { - npEvent.event = WM_MOUSEMOVE; - if (event->buttonDown()) - switch (event->button()) { - case LeftButton: - npEvent.wParam |= MK_LBUTTON; - break; - case MiddleButton: - npEvent.wParam |= MK_MBUTTON; - break; - case RightButton: - npEvent.wParam |= MK_RBUTTON; - break; - } - } - else if (event->type() == eventNames().mousedownEvent) { - focusPluginElement(); - switch (event->button()) { - case 0: - npEvent.event = WM_LBUTTONDOWN; - break; - case 1: - npEvent.event = WM_MBUTTONDOWN; - break; - case 2: - npEvent.event = WM_RBUTTONDOWN; - break; - } - } else if (event->type() == eventNames().mouseupEvent) { - switch (event->button()) { - case 0: - npEvent.event = WM_LBUTTONUP; - break; - case 1: - npEvent.event = WM_MBUTTONUP; - break; - case 2: - npEvent.event = WM_RBUTTONUP; - break; - } - } else - return; - - JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); - // FIXME: Consider back porting the http://webkit.org/b/58108 fix here. - if (dispatchNPEvent(npEvent)) - event->setDefaultHandled(); - -#if !PLATFORM(GTK) && !OS(WINCE) - // 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; - if (Page* page = m_parentFrame->page()) - page->chrome().client().setLastSetCursorToCurrentCursor(); -#endif -} - -void PluginView::setParent(ScrollView* parent) -{ - Widget::setParent(parent); - -#if OS(WINCE) - if (parent) { - init(); - if (parent->isVisible()) - show(); - else - hide(); - } -#else - if (parent) - init(); - else { - 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 (platformPluginWidget() == focusedWindow || ::IsChild(platformPluginWidget(), focusedWindow)) - ::SetFocus(0); - } -#endif -} - -void PluginView::setParentVisible(bool visible) -{ - if (isParentVisible() == visible) - return; - - Widget::setParentVisible(visible); - - if (isSelfVisible() && platformPluginWidget()) { - if (visible) - ShowWindow(platformPluginWidget(), SW_SHOWNA); - else - ShowWindow(platformPluginWidget(), SW_HIDE); - } -} - -void PluginView::setNPWindowRect(const IntRect& rect) -{ - if (!m_isStarted) - return; - -#if OS(WINCE) - IntRect r = toFrameView(parent())->contentsToWindow(rect); - m_npWindow.x = r.x(); - m_npWindow.y = r.y(); - - m_npWindow.width = r.width(); - m_npWindow.height = r.height(); - - m_npWindow.clipRect.right = r.width(); - m_npWindow.clipRect.bottom = r.height(); -#else - // In the GTK and Qt ports we draw in an offscreen buffer and don't want to use the window - // coordinates. -# if PLATFORM(GTK) - IntPoint p = rect.location(); -# else - IntPoint p = toFrameView(parent())->contentsToWindow(rect.location()); -# endif - m_npWindow.x = p.x(); - m_npWindow.y = p.y(); - - m_npWindow.width = rect.width(); - m_npWindow.height = rect.height(); - - m_npWindow.clipRect.right = rect.width(); - m_npWindow.clipRect.bottom = rect.height(); -#endif - m_npWindow.clipRect.left = 0; - m_npWindow.clipRect.top = 0; - - if (m_plugin->pluginFuncs()->setwindow) { - JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); - setCallingPlugin(true); - m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow); - setCallingPlugin(false); - - m_haveCalledSetWindow = true; - - if (!m_isWindowed) - return; - - ASSERT(platformPluginWidget()); - -#if OS(WINCE) - if (!m_pluginWndProc) { - WNDPROC currentWndProc = (WNDPROC)GetWindowLong(platformPluginWidget(), GWL_WNDPROC); - if (currentWndProc != PluginViewWndProc) - m_pluginWndProc = (WNDPROC)SetWindowLong(platformPluginWidget(), GWL_WNDPROC, (LONG)PluginViewWndProc); - } -#else - WNDPROC currentWndProc = (WNDPROC)GetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC); - if (currentWndProc != PluginViewWndProc) - m_pluginWndProc = (WNDPROC)SetWindowLongPtr(platformPluginWidget(), GWLP_WNDPROC, (LONG_PTR)PluginViewWndProc); -#endif - } -} - -NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf) -{ - String filename(buf, len); - - if (filename.startsWith("file:///")) - filename = filename.substring(8); - - // Get file info - WIN32_FILE_ATTRIBUTE_DATA attrs; - if (GetFileAttributesExW(filename.charactersWithNullTermination().data(), GetFileExInfoStandard, &attrs) == 0) - return NPERR_FILE_NOT_FOUND; - - if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - return NPERR_FILE_NOT_FOUND; - - HANDLE fileHandle = CreateFileW(filename.charactersWithNullTermination().data(), 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); - - CloseHandle(fileHandle); - - if (retval == 0 || bytesRead != attrs.nFileSizeLow) - return NPERR_FILE_NOT_FOUND; - - return NPERR_NO_ERROR; -} - -bool PluginView::platformGetValueStatic(NPNVariable, void*, NPError*) -{ - return false; -} - -bool PluginView::platformGetValue(NPNVariable variable, void* value, NPError* result) -{ - switch (variable) { - case NPNVnetscapeWindow: { - HWND* w = reinterpret_cast<HWND*>(value); - *w = windowHandleForPageClient(parent() ? parent()->hostWindow()->platformPageClient() : 0); - *result = NPERR_NO_ERROR; - return true; - } - - case NPNVSupportsWindowless: { - NPBool* flag = reinterpret_cast<NPBool*>(value); - *flag = TRUE; - *result = NPERR_NO_ERROR; - return true; - } - - default: - return false; - } -} - -void PluginView::invalidateRect(const IntRect& rect) -{ - if (m_isWindowed) { - RECT invalidRect = { rect.x(), rect.y(), rect.maxX(), rect.maxY() }; - ::InvalidateRect(platformPluginWidget(), &invalidRect, false); - 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); - - if (m_isWindowed) { - RECT invalidRect = { r.x(), r.y(), r.maxX(), r.maxY() }; - InvalidateRect(platformPluginWidget(), &invalidRect, FALSE); - } else { - if (m_plugin->quirks().contains(PluginQuirkThrottleInvalidate)) { - m_invalidRects.append(r); - if (!m_invalidateTimer.isActive()) - m_invalidateTimer.startOneShot(0.001); - } else - invalidateRect(r); - } -} - -void PluginView::invalidateRegion(NPRegion region) -{ - if (m_isWindowed) - return; - - RECT r; - - if (GetRgnBox(region, &r) == 0) { - invalidate(); - return; - } - - 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(platformPluginWidget()); - else - ::UpdateWindow(windowHandleForPageClient(parent() ? parent()->hostWindow()->platformPageClient() : 0)); -} - -bool PluginView::platformStart() -{ - ASSERT(m_isStarted); - ASSERT(m_status == PluginStatusLoadedSuccessfully); - - if (m_isWindowed) { - registerPluginView(); -#if !OS(WINCE) - setUpOffscreenPaintingHooks(hookedBeginPaint, hookedEndPaint); -#endif - - DWORD flags = WS_CHILD; - if (isSelfVisible()) - flags |= WS_VISIBLE; - - HWND parentWindowHandle = windowHandleForPageClient(m_parentFrame->view()->hostWindow()->platformPageClient()); - HWND window = ::CreateWindowEx(0, kWebPluginViewdowClassName, 0, flags, - 0, 0, 0, 0, parentWindowHandle, 0, WebCore::instanceHandle(), 0); - -#if OS(WINDOWS) && PLATFORM(GTK) - 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. -#if OS(WINDOWS) && CPU(X86_64) - ::SetWindowLongPtrA(platformPluginWidget(), GWLP_WNDPROC, (LONG_PTR)DefWindowProcA); -#elif OS(WINCE) - ::SetWindowLong(platformPluginWidget(), GWL_WNDPROC, (LONG)DefWindowProc); -#else - ::SetWindowLongPtrA(platformPluginWidget(), GWL_WNDPROC, (LONG)DefWindowProcA); -#endif - SetProp(platformPluginWidget(), kWebPluginViewProperty, this); - - m_npWindow.type = NPWindowTypeWindow; - m_npWindow.window = platformPluginWidget(); - } else { - m_npWindow.type = NPWindowTypeDrawable; - m_npWindow.window = 0; - } - - updatePluginWidget(); - - if (!m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)) - setNPWindowRect(frameRect()); - - return true; -} - -void PluginView::platformDestroy() -{ - if (!platformPluginWidget()) - return; - - DestroyWindow(platformPluginWidget()); - setPlatformPluginWidget(0); -} - -PassRefPtr<Image> PluginView::snapshot() -{ -#if !PLATFORM(GTK) && !USE(WINGDI) - auto hdc = adoptGDIObject(::CreateCompatibleDC(0)); - - if (!m_isWindowed) { - // Enable world transforms. - SetGraphicsMode(hdc.get(), GM_ADVANCED); - - XFORM transform; - GetWorldTransform(hdc.get(), &transform); - - // Windowless plug-ins assume that they're drawing onto the view's DC. - // Translate the context so that the plug-in draws at (0, 0). - ASSERT(parent()->isFrameView()); - IntPoint position = toFrameView(parent())->contentsToWindow(frameRect()).location(); - transform.eDx = -position.x(); - transform.eDy = -position.y(); - SetWorldTransform(hdc.get(), &transform); - } - - void* bits; - BitmapInfo bmp = BitmapInfo::createBottomUp(frameRect().size()); - auto hbmp = adoptGDIObject(::CreateDIBSection(0, &bmp, DIB_RGB_COLORS, &bits, 0, 0)); - - HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc.get(), hbmp.get())); - - paintIntoTransformedContext(hdc.get()); - - SelectObject(hdc.get(), hbmpOld); - - return BitmapImage::create(hbmp.get()); -#else - return 0; -#endif -} - -} // namespace WebCore |