summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2017-04-21 06:12:49 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-04-22 08:43:17 +0000
commitbd3f57b00bee3088971209a0ebc513eb1ef4ba14 (patch)
tree651d181d7348d440ff164909e8480297e4e7f18e
parent3b7091813e38631b9ca03ce9657c170ee8826439 (diff)
Import WebKit commit 584c4a7a6a8bffb60f03b9eb10a65dbcf41dc0b7
Change-Id: Ife943bbbd8226afa05ef6320b10ba351d55fd797 Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
-rw-r--r--Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp2
-rw-r--r--Source/JavaScriptCore/ftl/FTLState.cpp2
-rw-r--r--Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp2
-rw-r--r--Source/WebCore/PlatformQt.cmake4
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h487
-rw-r--r--Source/WebCore/platform/network/qt/CookieJarQt.cpp120
-rw-r--r--Source/WebCore/platform/network/qt/CookieJarQt.h7
-rw-r--r--Source/WebCore/platform/win/BString.cpp197
-rw-r--r--Source/WebCore/platform/win/BString.h83
-rw-r--r--Source/WebCore/platform/win/COMPtr.h245
-rw-r--r--Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp841
-rw-r--r--Source/WebCore/platform/win/ClipboardUtilitiesWin.h89
-rw-r--r--Source/WebCore/platform/win/CursorWin.cpp296
-rw-r--r--Source/WebCore/platform/win/DefWndProcWindowClass.cpp52
-rw-r--r--Source/WebCore/platform/win/DefWndProcWindowClass.h38
-rw-r--r--Source/WebCore/platform/win/DelayLoadedModulesEnumerator.cpp86
-rw-r--r--Source/WebCore/platform/win/DelayLoadedModulesEnumerator.h56
-rw-r--r--Source/WebCore/platform/win/DragDataWin.cpp210
-rw-r--r--Source/WebCore/platform/win/DragImageCGWin.cpp149
-rw-r--r--Source/WebCore/platform/win/DragImageCairoWin.cpp177
-rw-r--r--Source/WebCore/platform/win/DragImageWin.cpp217
-rw-r--r--Source/WebCore/platform/win/EventLoopWin.cpp45
-rw-r--r--Source/WebCore/platform/win/FileSystemWin.cpp450
-rw-r--r--Source/WebCore/platform/win/GDIObjectCounter.cpp74
-rw-r--r--Source/WebCore/platform/win/GDIObjectCounter.h63
-rw-r--r--Source/WebCore/platform/win/GDIUtilities.cpp39
-rw-r--r--Source/WebCore/platform/win/GDIUtilities.h37
-rw-r--r--Source/WebCore/platform/win/HWndDC.h89
-rw-r--r--Source/WebCore/platform/win/ImportedFunctionsEnumerator.cpp75
-rw-r--r--Source/WebCore/platform/win/ImportedFunctionsEnumerator.h58
-rw-r--r--Source/WebCore/platform/win/ImportedModulesEnumerator.cpp73
-rw-r--r--Source/WebCore/platform/win/ImportedModulesEnumerator.h52
-rw-r--r--Source/WebCore/platform/win/ImportedModulesEnumeratorBase.h47
-rw-r--r--Source/WebCore/platform/win/KeyEventWin.cpp255
-rw-r--r--Source/WebCore/platform/win/LanguageWin.cpp77
-rw-r--r--Source/WebCore/platform/win/LocalizedStringsWin.cpp62
-rw-r--r--Source/WebCore/platform/win/LoggingWin.cpp55
-rw-r--r--Source/WebCore/platform/win/MIMETypeRegistryWin.cpp115
-rw-r--r--Source/WebCore/platform/win/MainThreadSharedTimerWin.cpp198
-rw-r--r--Source/WebCore/platform/win/MemoryPressureHandlerWin.cpp135
-rw-r--r--Source/WebCore/platform/win/PEImage.cpp74
-rw-r--r--Source/WebCore/platform/win/PEImage.h54
-rw-r--r--Source/WebCore/platform/win/PasteboardWin.cpp1060
-rw-r--r--Source/WebCore/platform/win/PathWalker.cpp51
-rw-r--r--Source/WebCore/platform/win/PathWalker.h51
-rw-r--r--Source/WebCore/platform/win/PlatformMouseEventWin.cpp125
-rw-r--r--Source/WebCore/platform/win/PlatformScreenWin.cpp104
-rw-r--r--Source/WebCore/platform/win/PopupMenuWin.cpp1422
-rw-r--r--Source/WebCore/platform/win/PopupMenuWin.h189
-rw-r--r--Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp100
-rw-r--r--Source/WebCore/platform/win/ScrollbarThemeWin.cpp403
-rw-r--r--Source/WebCore/platform/win/ScrollbarThemeWin.h62
-rw-r--r--Source/WebCore/platform/win/SearchPopupMenuWin.cpp101
-rw-r--r--Source/WebCore/platform/win/SearchPopupMenuWin.h44
-rw-r--r--Source/WebCore/platform/win/SharedBufferWin.cpp66
-rw-r--r--Source/WebCore/platform/win/SoftLinking.h322
-rw-r--r--Source/WebCore/platform/win/SoundWin.cpp36
-rw-r--r--Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp143
-rw-r--r--Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.h53
-rw-r--r--Source/WebCore/platform/win/TemporaryLinkStubs.cpp45
-rw-r--r--Source/WebCore/platform/win/WCDataObject.cpp365
-rw-r--r--Source/WebCore/platform/win/WCDataObject.h78
-rw-r--r--Source/WebCore/platform/win/WebCoreBundleWin.cpp67
-rw-r--r--Source/WebCore/platform/win/WebCoreBundleWin.h41
-rw-r--r--Source/WebCore/platform/win/WebCoreTextRenderer.cpp117
-rw-r--r--Source/WebCore/platform/win/WebCoreTextRenderer.h49
-rw-r--r--Source/WebCore/platform/win/WheelEventWin.cpp142
-rw-r--r--Source/WebCore/platform/win/WidgetWin.cpp101
-rw-r--r--Source/WebCore/platform/win/Win32Handle.h68
-rw-r--r--Source/WebCore/platform/win/WindowMessageBroadcaster.cpp128
-rw-r--r--Source/WebCore/platform/win/WindowMessageBroadcaster.h70
-rw-r--r--Source/WebCore/platform/win/WindowMessageListener.h43
-rw-r--r--Source/WebCore/platform/win/WindowsTouch.h116
-rw-r--r--Source/WebCore/platform/win/makesafeseh.asm45
-rw-r--r--Source/WebKit/PlatformQt.cmake48
-rw-r--r--Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp17
-rw-r--r--Source/WebKit/qt/tests/CMakeLists.txt2
-rw-r--r--Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp14
-rw-r--r--Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp4
-rw-r--r--Source/cmake/ECMGeneratePriFile.cmake28
-rw-r--r--Source/cmake/KDEInstallDirs.cmake4
-rw-r--r--Source/cmake/OptionsCommon.cmake4
-rw-r--r--Source/cmake/OptionsQt.cmake17
-rw-r--r--Tools/PlatformQt.cmake2
-rw-r--r--Tools/qmake/projects/run_cmake.pro13
-rw-r--r--Tools/qt/manifest.txt8
86 files changed, 11353 insertions, 102 deletions
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 06d114861..4f6e8fbb4 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -375,7 +375,7 @@ RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
handleSpread:
RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(length));
- auto spreader = [this, array, index](BytecodeGenerator& generator, RegisterID* value)
+ auto spreader = [array, index](BytecodeGenerator& generator, RegisterID* value)
{
generator.emitDirectPutByVal(array.get(), index.get(), value);
generator.emitInc(index.get());
diff --git a/Source/JavaScriptCore/ftl/FTLState.cpp b/Source/JavaScriptCore/ftl/FTLState.cpp
index d62433700..2b90aa44a 100644
--- a/Source/JavaScriptCore/ftl/FTLState.cpp
+++ b/Source/JavaScriptCore/ftl/FTLState.cpp
@@ -67,7 +67,7 @@ State::State(Graph& graph)
proc = std::make_unique<Procedure>();
proc->setOriginPrinter(
- [this] (PrintStream& out, B3::Origin origin) {
+ [] (PrintStream& out, B3::Origin origin) {
out.print("DFG:", bitwise_cast<Node*>(origin.data()));
});
diff --git a/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp b/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
index 1550df4c1..b886b1372 100644
--- a/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
+++ b/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
@@ -578,7 +578,7 @@ IDBError SQLiteIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo& info
if (!m_sqliteDB)
return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to open database file on disk") };
- m_sqliteDB->setCollationFunction("IDBKEY", [this](int aLength, const void* a, int bLength, const void* b) {
+ m_sqliteDB->setCollationFunction("IDBKEY", [](int aLength, const void* a, int bLength, const void* b) {
return idbKeyCollate(aLength, a, bLength, b);
});
diff --git a/Source/WebCore/PlatformQt.cmake b/Source/WebCore/PlatformQt.cmake
index 5d2d01cc9..3f839b0dd 100644
--- a/Source/WebCore/PlatformQt.cmake
+++ b/Source/WebCore/PlatformQt.cmake
@@ -161,7 +161,7 @@ if (COMPILER_IS_GCC_OR_CLANG)
set_source_files_properties(
platform/graphics/qt/ImageBufferDataQt.cpp
PROPERTIES
- COMPILE_FLAGS -frtti
+ COMPILE_FLAGS "-frtti -UQT_NO_DYNAMIC_CAST"
)
endif ()
@@ -234,7 +234,6 @@ list(APPEND WebCore_SYSTEM_INCLUDE_DIRECTORIES
${Qt5Gui_PRIVATE_INCLUDE_DIRS}
${Qt5Network_INCLUDE_DIRS}
${Qt5Sensors_INCLUDE_DIRS}
- ${Qt5Sql_INCLUDE_DIRS}
${SQLITE_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
)
@@ -247,7 +246,6 @@ list(APPEND WebCore_LIBRARIES
${Qt5Gui_LIBRARIES}
${Qt5Network_LIBRARIES}
${Qt5Sensors_LIBRARIES}
- ${Qt5Sql_LIBRARIES}
${SQLITE_LIBRARIES}
${ZLIB_LIBRARIES}
)
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h
new file mode 100644
index 000000000..2fdce58ee
--- /dev/null
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2014 Alex Christensen <achristensen@webkit.org>
+ * 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 MediaPlayerPrivateMediaFoundation_h
+#define MediaPlayerPrivateMediaFoundation_h
+
+#include "COMPtr.h"
+#include "MediaPlayerPrivate.h"
+#include "Win32Handle.h"
+
+#include <D3D9.h>
+#include <Dxva2api.h>
+
+#include <Mfapi.h>
+#include <Mferror.h>
+#include <Mfidl.h>
+#include <evcode.h>
+#include <evr.h>
+
+#include <wtf/Deque.h>
+#include <wtf/Lock.h>
+#include <wtf/ThreadingPrimitives.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+class MediaPlayerPrivateMediaFoundation : public MediaPlayerPrivateInterface {
+public:
+ explicit MediaPlayerPrivateMediaFoundation(MediaPlayer*);
+ ~MediaPlayerPrivateMediaFoundation();
+ static void registerMediaEngine(MediaEngineRegistrar);
+
+ static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types);
+ static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);
+ static bool isAvailable();
+
+ void load(const String& url) override;
+ void cancelLoad() override;
+
+ void prepareToPlay() override;
+
+ void play() override;
+ void pause() override;
+
+ bool supportsFullscreen() const override;
+
+ FloatSize naturalSize() const override;
+
+ bool hasVideo() const override;
+ bool hasAudio() const override;
+
+ void setVisible(bool) override;
+
+ bool seeking() const override;
+ void seek(float) override;
+
+ void setRate(float) override;
+
+ float duration() const override;
+
+ float currentTime() const override;
+
+ bool paused() const override;
+
+ void setVolume(float) override;
+
+ bool supportsMuting() const override;
+ void setMuted(bool) override;
+
+ MediaPlayer::NetworkState networkState() const override;
+ MediaPlayer::ReadyState readyState() const override;
+
+ float maxTimeSeekable() const override;
+
+ std::unique_ptr<PlatformTimeRanges> buffered() const override;
+
+ bool didLoadingProgress() const override;
+
+ void setSize(const IntSize&) override;
+
+ void paint(GraphicsContext&, const FloatRect&) override;
+
+private:
+ MediaPlayer* m_player;
+ IntSize m_size;
+ bool m_visible;
+ bool m_loadingProgress;
+ bool m_paused;
+ bool m_hasAudio;
+ bool m_hasVideo;
+ bool m_preparingToPlay;
+ HWND m_hwndVideo;
+ MediaPlayer::NetworkState m_networkState;
+ MediaPlayer::ReadyState m_readyState;
+ FloatRect m_lastPaintRect;
+
+ class MediaPlayerListener;
+ HashSet<MediaPlayerListener*> m_listeners;
+ Lock m_mutexListeners;
+
+ WeakPtrFactory<MediaPlayerPrivateMediaFoundation> m_weakPtrFactory;
+ COMPtr<IMFMediaSession> m_mediaSession;
+ COMPtr<IMFSourceResolver> m_sourceResolver;
+ COMPtr<IMFMediaSource> m_mediaSource;
+ COMPtr<IMFTopology> m_topology;
+ COMPtr<IMFPresentationDescriptor> m_sourcePD;
+ COMPtr<IMFVideoDisplayControl> m_videoDisplay;
+
+ bool createSession();
+ bool startSession();
+ bool endSession();
+ bool startCreateMediaSource(const String& url);
+ bool endCreatedMediaSource(IMFAsyncResult*);
+ bool endGetEvent(IMFAsyncResult*);
+ bool createTopologyFromSource();
+ bool addBranchToPartialTopology(int stream);
+ bool createOutputNode(COMPtr<IMFStreamDescriptor> sourceSD, COMPtr<IMFTopologyNode>&);
+ bool createSourceStreamNode(COMPtr<IMFStreamDescriptor> sourceSD, COMPtr<IMFTopologyNode>&);
+
+ void updateReadyState();
+
+ COMPtr<IMFVideoDisplayControl> videoDisplay();
+
+ void onCreatedMediaSource();
+ void onTopologySet();
+ void onBufferingStarted();
+ void onBufferingStopped();
+ void onSessionEnded();
+
+ LPCWSTR registerVideoWindowClass();
+ void createVideoWindow();
+ void destroyVideoWindow();
+
+ void invalidateFrameView();
+
+ void addListener(MediaPlayerListener*);
+ void removeListener(MediaPlayerListener*);
+ void notifyDeleted();
+
+ static LRESULT CALLBACK VideoViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+ class MediaPlayerListener {
+ public:
+ MediaPlayerListener() { }
+ virtual ~MediaPlayerListener() { }
+
+ virtual void onMediaPlayerDeleted() { }
+ };
+
+ class AsyncCallback : public IMFAsyncCallback, public MediaPlayerListener {
+ public:
+ AsyncCallback(MediaPlayerPrivateMediaFoundation*, bool event);
+ ~AsyncCallback();
+
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) override;
+ virtual ULONG STDMETHODCALLTYPE AddRef() override;
+ virtual ULONG STDMETHODCALLTYPE Release() override;
+
+ virtual HRESULT STDMETHODCALLTYPE GetParameters(__RPC__out DWORD *pdwFlags, __RPC__out DWORD *pdwQueue) override;
+ virtual HRESULT STDMETHODCALLTYPE Invoke(__RPC__in_opt IMFAsyncResult *pAsyncResult) override;
+
+ virtual void onMediaPlayerDeleted() override;
+
+ private:
+ ULONG m_refCount;
+ MediaPlayerPrivateMediaFoundation* m_mediaPlayer;
+ bool m_event;
+ Lock m_mutex;
+ };
+
+ typedef Deque<COMPtr<IMFSample>> VideoSampleList;
+
+ class VideoSamplePool {
+ public:
+ VideoSamplePool() { }
+ virtual ~VideoSamplePool() { }
+
+ HRESULT initialize(VideoSampleList& samples);
+ void clear();
+
+ HRESULT getSample(COMPtr<IMFSample>&);
+ HRESULT returnSample(IMFSample*);
+ bool areSamplesPending();
+
+ private:
+ Lock m_lock;
+ VideoSampleList m_videoSampleQueue;
+ bool m_initialized { false };
+ unsigned m_pending { 0 };
+ };
+
+ class Direct3DPresenter;
+
+ class VideoScheduler {
+ public:
+ VideoScheduler() { }
+ virtual ~VideoScheduler() { }
+
+ void setPresenter(Direct3DPresenter* presenter) { m_presenter = presenter; }
+
+ void setFrameRate(const MFRatio& fps);
+ void setClockRate(float rate) { m_playbackRate = rate; }
+
+ const LONGLONG& lastSampleTime() const { return m_lastSampleTime; }
+ const LONGLONG& frameDuration() const { return m_frameDuration; }
+
+ HRESULT startScheduler(IMFClock*);
+ HRESULT stopScheduler();
+
+ HRESULT scheduleSample(IMFSample*, bool presentNow);
+ HRESULT processSamplesInQueue(LONG& nextSleep);
+ HRESULT processSample(IMFSample*, LONG& nextSleep);
+ HRESULT flush();
+
+ private:
+ static DWORD WINAPI schedulerThreadProc(LPVOID lpParameter);
+ DWORD schedulerThreadProcPrivate();
+
+ Deque<COMPtr<IMFSample>> m_scheduledSamples;
+ Lock m_lock;
+
+ COMPtr<IMFClock> m_clock;
+ Direct3DPresenter* m_presenter { nullptr };
+
+ DWORD m_threadID { 0 };
+ Win32Handle m_schedulerThread;
+ Win32Handle m_threadReadyEvent;
+ Win32Handle m_flushEvent;
+
+ float m_playbackRate { 1.0f };
+ MFTIME m_frameDuration { 0 };
+ MFTIME m_lastSampleTime { 0 };
+
+ std::atomic<bool> m_exitThread { false };
+
+ void stopThread() { m_exitThread = true; }
+ };
+
+ class Direct3DPresenter {
+ public:
+ Direct3DPresenter();
+ ~Direct3DPresenter();
+
+ enum DeviceState {
+ DeviceOK,
+ DeviceReset,
+ DeviceRemoved,
+ };
+
+ // Returns the IDirect3DDeviceManager9 interface.
+ HRESULT getService(REFGUID guidService, REFIID riid, void** ppv);
+
+ HRESULT checkFormat(D3DFORMAT);
+
+ HRESULT setVideoWindow(HWND);
+ HWND getVideoWindow() const { return m_hwnd; }
+ HRESULT setDestinationRect(const RECT& destRect);
+ RECT getDestinationRect() const { return m_destRect; };
+
+ HRESULT createVideoSamples(IMFMediaType* format, VideoSampleList& videoSampleQueue);
+ void releaseResources();
+
+ HRESULT checkDeviceState(DeviceState&);
+ HRESULT presentSample(IMFSample*, LONGLONG target);
+
+ UINT refreshRate() const { return m_displayMode.RefreshRate; }
+
+ void paintCurrentFrame(GraphicsContext&, const FloatRect&);
+
+ private:
+ HRESULT initializeD3D();
+ HRESULT getSwapChainPresentParameters(IMFMediaType*, D3DPRESENT_PARAMETERS* presentParams);
+ HRESULT createD3DDevice();
+ HRESULT createD3DSample(IDirect3DSwapChain9*, COMPtr<IMFSample>& videoSample);
+ HRESULT updateDestRect();
+
+ HRESULT presentSwapChain(IDirect3DSwapChain9*, IDirect3DSurface9*);
+
+ UINT m_deviceResetToken { 0 };
+ HWND m_hwnd { nullptr };
+ RECT m_destRect;
+ D3DDISPLAYMODE m_displayMode;
+
+ Lock m_lock;
+
+ COMPtr<IDirect3D9Ex> m_direct3D9;
+ COMPtr<IDirect3DDevice9Ex> m_device;
+ COMPtr<IDirect3DDeviceManager9> m_deviceManager;
+ COMPtr<IDirect3DSurface9> m_surfaceRepaint;
+
+ COMPtr<IDirect3DSurface9> m_memSurface;
+ int m_width { 0 };
+ int m_height { 0 };
+ };
+
+ class CustomVideoPresenter
+ : public IMFVideoPresenter
+ , public IMFVideoDeviceID
+ , public IMFTopologyServiceLookupClient
+ , public IMFGetService
+ , public IMFActivate
+ , public IMFVideoDisplayControl
+ , public IMFAsyncCallback
+ , public MediaPlayerListener {
+ public:
+ CustomVideoPresenter(MediaPlayerPrivateMediaFoundation*);
+ ~CustomVideoPresenter();
+
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) override;
+ virtual ULONG STDMETHODCALLTYPE AddRef() override;
+ virtual ULONG STDMETHODCALLTYPE Release() override;
+
+ // IMFClockStateSink
+ virtual HRESULT STDMETHODCALLTYPE OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) override;
+ virtual HRESULT STDMETHODCALLTYPE OnClockStop(MFTIME hnsSystemTime) override;
+ virtual HRESULT STDMETHODCALLTYPE OnClockPause(MFTIME hnsSystemTime) override;
+ virtual HRESULT STDMETHODCALLTYPE OnClockRestart(MFTIME hnsSystemTime) override;
+ virtual HRESULT STDMETHODCALLTYPE OnClockSetRate(MFTIME hnsSystemTime, float flRate) override;
+
+ // IMFVideoPresenter
+ virtual HRESULT STDMETHODCALLTYPE ProcessMessage(MFVP_MESSAGE_TYPE eMessage, ULONG_PTR ulParam) override;
+ virtual HRESULT STDMETHODCALLTYPE GetCurrentMediaType(_Outptr_ IMFVideoMediaType **ppMediaType) override;
+
+ // IMFVideoDeviceID
+ virtual HRESULT STDMETHODCALLTYPE GetDeviceID(IID* pDeviceID) override;
+
+ // IMFTopologyServiceLookupClient
+ virtual HRESULT STDMETHODCALLTYPE InitServicePointers(_In_ IMFTopologyServiceLookup *pLookup) override;
+ virtual HRESULT STDMETHODCALLTYPE ReleaseServicePointers(void) override;
+
+ // IMFGetService
+ virtual HRESULT STDMETHODCALLTYPE GetService(REFGUID guidService, REFIID riid, LPVOID *ppvObject);
+
+ // IMFActivate
+ virtual HRESULT STDMETHODCALLTYPE ActivateObject(REFIID riid, void **ppv);
+ virtual HRESULT STDMETHODCALLTYPE DetachObject();
+ virtual HRESULT STDMETHODCALLTYPE ShutdownObject();
+
+ // IMFAttributes
+ virtual HRESULT STDMETHODCALLTYPE GetItem(__RPC__in REFGUID guidKey, __RPC__inout_opt PROPVARIANT *pValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetItemType(__RPC__in REFGUID guidKey, __RPC__out MF_ATTRIBUTE_TYPE *pType) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE CompareItem(__RPC__in REFGUID guidKey, __RPC__in REFPROPVARIANT Value, __RPC__out BOOL *pbResult) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt IMFAttributes *pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, __RPC__out BOOL *pbResult) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetUINT32(__RPC__in REFGUID guidKey, __RPC__out UINT32 *punValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetUINT64(__RPC__in REFGUID guidKey, __RPC__out UINT64 *punValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetDouble(__RPC__in REFGUID guidKey, __RPC__out double *pfValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetGUID(__RPC__in REFGUID guidKey, __RPC__out GUID *pguidValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetStringLength(__RPC__in REFGUID guidKey, __RPC__out UINT32 *pcchLength) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetString(__RPC__in REFGUID guidKey, __RPC__out_ecount_full(cchBufSize) LPWSTR pwszValue, UINT32 cchBufSize, __RPC__inout_opt UINT32 *pcchLength) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetAllocatedString(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt((*pcchLength + 1)) LPWSTR *ppwszValue, __RPC__out UINT32 *pcchLength) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetBlobSize(__RPC__in REFGUID guidKey, __RPC__out UINT32 *pcbBlobSize) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetBlob(__RPC__in REFGUID guidKey, __RPC__out_ecount_full(cbBufSize) UINT8 *pBuf, UINT32 cbBufSize, __RPC__inout_opt UINT32 *pcbBlobSize) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetAllocatedBlob(__RPC__in REFGUID guidKey, __RPC__deref_out_ecount_full_opt(*pcbSize) UINT8 **ppBuf, __RPC__out UINT32 *pcbSize) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetUnknown(__RPC__in REFGUID guidKey, __RPC__in REFIID riid, __RPC__deref_out_opt LPVOID *ppv) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetItem(__RPC__in REFGUID guidKey, __RPC__in REFPROPVARIANT Value) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE DeleteItem(__RPC__in REFGUID guidKey) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE DeleteAllItems(void) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetUINT32(__RPC__in REFGUID guidKey, UINT32 unValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetUINT64(__RPC__in REFGUID guidKey, UINT64 unValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetDouble(__RPC__in REFGUID guidKey, double fValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetGUID(__RPC__in REFGUID guidKey, __RPC__in REFGUID guidValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetString(__RPC__in REFGUID guidKey, __RPC__in_string LPCWSTR wszValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetBlob(__RPC__in REFGUID guidKey, __RPC__in_ecount_full(cbBufSize) const UINT8 *pBuf, UINT32 cbBufSize) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetUnknown(__RPC__in REFGUID guidKey, __RPC__in_opt IUnknown *pUnknown) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE LockStore(void) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE UnlockStore(void) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetCount(__RPC__out UINT32 *pcItems) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetItemByIndex(UINT32 unIndex, __RPC__out GUID *pguidKey, __RPC__inout_opt PROPVARIANT *pValue) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE CopyAllItems(__RPC__in_opt IMFAttributes *pDest) { return E_NOTIMPL; }
+
+ // IMFVideoDisplayControl
+ virtual HRESULT STDMETHODCALLTYPE GetNativeVideoSize(SIZE* pszVideo, SIZE* pszARVideo) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetIdealVideoSize(SIZE* pszMin, SIZE* pszMax) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetVideoPosition(const MFVideoNormalizedRect* pnrcSource, const LPRECT prcDest);
+ virtual HRESULT STDMETHODCALLTYPE GetVideoPosition(MFVideoNormalizedRect* pnrcSource, LPRECT prcDest);
+ virtual HRESULT STDMETHODCALLTYPE SetAspectRatioMode(DWORD dwAspectRatioMode) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetAspectRatioMode(DWORD* pdwAspectRatioMode) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetVideoWindow(HWND hwndVideo);
+ virtual HRESULT STDMETHODCALLTYPE GetVideoWindow(HWND* phwndVideo);
+ virtual HRESULT STDMETHODCALLTYPE RepaintVideo();
+ virtual HRESULT STDMETHODCALLTYPE GetCurrentImage(BITMAPINFOHEADER* pBih, BYTE** pDib, DWORD* pcbDib, LONGLONG* pTimeStamp) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetBorderColor(COLORREF Clr) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetBorderColor(COLORREF* pClr) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetRenderingPrefs(DWORD dwRenderFlags) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetRenderingPrefs(DWORD* pdwRenderFlags) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE SetFullscreen(BOOL bFullscreen) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE GetFullscreen(BOOL* pbFullscreen) { return E_NOTIMPL; }
+
+ // IMFAsyncCallback methods
+ virtual HRESULT STDMETHODCALLTYPE GetParameters(DWORD*, DWORD*) { return E_NOTIMPL; }
+ virtual HRESULT STDMETHODCALLTYPE Invoke(IMFAsyncResult* pAsyncResult);
+
+ // MediaPlayerListener
+ virtual void onMediaPlayerDeleted() override;
+
+ void paintCurrentFrame(GraphicsContext&, const FloatRect&);
+
+ float currentTime();
+
+ float maxTimeLoaded() const { return m_maxTimeLoaded; }
+
+ private:
+ ULONG m_refCount { 0 };
+ Lock m_lock;
+ MediaPlayerPrivateMediaFoundation* m_mediaPlayer;
+
+ enum RenderState {
+ RenderStateStarted = 1,
+ RenderStateStopped,
+ RenderStatePaused,
+ RenderStateShutdown,
+ };
+
+ RenderState m_renderState { RenderStateShutdown };
+ COMPtr<IMFClock> m_clock;
+ COMPtr<IMediaEventSink> m_mediaEventSink;
+ COMPtr<IMFTransform> m_mixer;
+ COMPtr<IMFMediaType> m_mediaType;
+ std::unique_ptr<Direct3DPresenter> m_presenterEngine;
+ MFVideoNormalizedRect m_sourceRect;
+ bool m_sampleNotify { false };
+ bool m_prerolled { false };
+ bool m_repaint { false };
+ bool m_endStreaming { false };
+ VideoScheduler m_scheduler;
+ VideoSamplePool m_samplePool;
+ unsigned m_tokenCounter { 0 };
+ float m_rate { 1.0f };
+ float m_maxTimeLoaded { 0.0f };
+
+ bool isActive() const;
+
+ bool isScrubbing() const { return m_rate == 0.0f; }
+
+ HRESULT configureMixer(IMFTransform* mixer);
+ HRESULT flush();
+ HRESULT setMediaType(IMFMediaType*);
+ HRESULT checkShutdown() const;
+ HRESULT renegotiateMediaType();
+ HRESULT processInputNotify();
+ HRESULT beginStreaming();
+ HRESULT endStreaming();
+ HRESULT checkEndOfStream();
+ HRESULT isMediaTypeSupported(IMFMediaType*);
+ HRESULT createOptimalVideoType(IMFMediaType* proposedType, IMFMediaType** optimalType);
+ HRESULT calculateOutputRectangle(IMFMediaType* proposedType, RECT& outputRect);
+
+ void processOutputLoop();
+ HRESULT processOutput();
+ HRESULT deliverSample(IMFSample*, bool repaint);
+ HRESULT trackSample(IMFSample*);
+ void releaseResources();
+
+ HRESULT onSampleFree(IMFAsyncResult*);
+
+ void notifyEvent(long EventCode, LONG_PTR Param1, LONG_PTR Param2);
+ };
+
+ COMPtr<CustomVideoPresenter> m_presenter;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/network/qt/CookieJarQt.cpp b/Source/WebCore/platform/network/qt/CookieJarQt.cpp
index 9c2465d8f..020727cc7 100644
--- a/Source/WebCore/platform/network/qt/CookieJarQt.cpp
+++ b/Source/WebCore/platform/network/qt/CookieJarQt.cpp
@@ -33,11 +33,12 @@
#include "URL.h"
#include "NetworkingContext.h"
#include "PlatformCookieJar.h"
+#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
#include "ThirdPartyCookiesQt.h"
#include <QDateTime>
#include <QNetworkAccessManager>
#include <QNetworkCookie>
-#include <QSqlQuery>
#include <QStringList>
#include <QVariant>
#include <wtf/text/WTFString.h>
@@ -187,11 +188,18 @@ bool SharedCookieJarQt::deleteCookie(const QNetworkCookie& cookie)
if (!m_database.isOpen())
return false;
- QSqlQuery sqlQuery(m_database);
- sqlQuery.prepare(QLatin1String("DELETE FROM cookies WHERE cookieId=:cookieIdvalue"));
- sqlQuery.bindValue(QLatin1String(":cookieIdvalue"), cookie.domain().append(QLatin1String(cookie.name())));
- sqlQuery.exec();
+ SQLiteStatement sqlQuery(m_database, ASCIILiteral("DELETE FROM cookies WHERE cookieId=?"));
+ if (sqlQuery.prepare() != SQLITE_OK) {
+ qWarning("Failed to prepare delete statement - cannot write to cookie database");
+ return false;
+ }
+ sqlQuery.bindText(1, cookie.domain().append(QLatin1String(cookie.name())));
+ int result = sqlQuery.step();
+ if (result != SQLITE_DONE) {
+ qWarning("Failed to delete cookie from database - %i", result);
+ return false;
+ }
return true;
}
@@ -203,16 +211,27 @@ void SharedCookieJarQt::deleteCookiesForHostname(const String& hostname)
QList<QNetworkCookie> cookies = allCookies();
QList<QNetworkCookie>::Iterator it = cookies.begin();
QList<QNetworkCookie>::Iterator end = cookies.end();
- QSqlQuery sqlQuery(m_database);
- sqlQuery.prepare(QLatin1String("DELETE FROM cookies WHERE cookieId=:cookieIdvalue"));
+ SQLiteStatement sqlQuery(m_database, ASCIILiteral("DELETE FROM cookies WHERE cookieId=?"));
+ if (sqlQuery.prepare() != SQLITE_OK) {
+ qWarning("Failed to prepare delete statement - cannot write to cookie database");
+ return;
+ }
+
+ SQLiteTransaction transaction(m_database);
+ transaction.begin();
while (it != end) {
if (it->domain() == QString(hostname)) {
- sqlQuery.bindValue(QLatin1String(":cookieIdvalue"), it->domain().append(QLatin1String(it->name())));
- sqlQuery.exec();
+ sqlQuery.bindText(1, it->domain().append(QLatin1String(it->name())));
+ int result = sqlQuery.step();
+ if (result != SQLITE_DONE)
+ qWarning("Failed to remove cookie from database - %i", result);
+ sqlQuery.reset();
it = cookies.erase(it);
} else
it++;
}
+ transaction.commit();
+
setAllCookies(cookies);
}
@@ -221,20 +240,25 @@ void SharedCookieJarQt::deleteAllCookies()
if (!m_database.isOpen())
return;
- QSqlQuery sqlQuery(m_database);
- sqlQuery.prepare(QLatin1String("DELETE FROM cookies"));
- sqlQuery.exec();
+ if (!m_database.executeCommand(ASCIILiteral("DELETE FROM cookies")))
+ qWarning("Failed to clear cookies database");
setAllCookies(QList<QNetworkCookie>());
}
SharedCookieJarQt::SharedCookieJarQt(const String& cookieStorageDirectory)
{
- m_database = QSqlDatabase::addDatabase(QLatin1String("QSQLITE"));
- const QString cookieStoragePath = cookieStorageDirectory;
- const QString dataBaseName = cookieStoragePath + QLatin1String("/cookies.db");
- m_database.setDatabaseName(dataBaseName);
- ensureDatabaseTable();
- loadCookies();
+ if (!m_database.open(cookieStorageDirectory + ASCIILiteral("/cookies.db"))) {
+ qWarning("Can't open cookie database");
+ return;
+ }
+
+ m_database.setSynchronous(SQLiteDatabase::SyncOff);
+ m_database.executeCommand(ASCIILiteral("PRAGMA secure_delete = 1;"));
+
+ if (ensureDatabaseTable())
+ loadCookies();
+ else
+ m_database.close();
}
SharedCookieJarQt::~SharedCookieJarQt()
@@ -250,33 +274,35 @@ bool SharedCookieJarQt::setCookiesFromUrl(const QList<QNetworkCookie>& cookieLis
if (!m_database.isOpen())
return false;
- QSqlQuery sqlQuery(m_database);
- sqlQuery.prepare(QLatin1String("INSERT OR REPLACE INTO cookies (cookieId, cookie) VALUES (:cookieIdvalue, :cookievalue)"));
- QVariantList cookiesIds;
- QVariantList cookiesValues;
+ SQLiteStatement sqlQuery(m_database, ASCIILiteral("INSERT OR REPLACE INTO cookies (cookieId, cookie) VALUES (?, ?)"));
+ if (sqlQuery.prepare() != SQLITE_OK)
+ return false;
+
+ SQLiteTransaction transaction(m_database);
+ transaction.begin();
foreach (const QNetworkCookie &cookie, cookiesForUrl(url)) {
if (cookie.isSessionCookie())
continue;
- cookiesIds.append(cookie.domain().append(QLatin1String(cookie.name())));
- cookiesValues.append(cookie.toRawForm());
+ sqlQuery.bindText(1, cookie.domain().append(QLatin1String(cookie.name())));
+ QByteArray rawCookie = cookie.toRawForm();
+ sqlQuery.bindBlob(2, rawCookie.constData(), rawCookie.size());
+ int result = sqlQuery.step();
+ if (result != SQLITE_DONE)
+ qWarning("Failed to insert cookie into database - %i", result);
+ sqlQuery.reset();
}
- sqlQuery.bindValue(QLatin1String(":cookieIdvalue"), cookiesIds);
- sqlQuery.bindValue(QLatin1String(":cookievalue"), cookiesValues);
- sqlQuery.execBatch();
+ transaction.commit();
+
return true;
}
-void SharedCookieJarQt::ensureDatabaseTable()
+bool SharedCookieJarQt::ensureDatabaseTable()
{
- if (!m_database.open()) {
- qWarning("Can't open cookie database");
- return;
+ if (!m_database.executeCommand(ASCIILiteral("CREATE TABLE IF NOT EXISTS cookies (cookieId VARCHAR PRIMARY KEY, cookie BLOB);"))) {
+ qWarning("Failed to create cookie table");
+ return false;
}
- m_database.exec(QLatin1String("PRAGMA synchronous=OFF"));
-
- QSqlQuery sqlQuery(m_database);
- sqlQuery.prepare(QLatin1String("CREATE TABLE IF NOT EXISTS cookies (cookieId VARCHAR PRIMARY KEY, cookie BLOB);"));
- sqlQuery.exec();
+ return true;
}
void SharedCookieJarQt::loadCookies()
@@ -285,11 +311,23 @@ void SharedCookieJarQt::loadCookies()
return;
QList<QNetworkCookie> cookies;
- QSqlQuery sqlQuery(m_database);
- sqlQuery.prepare(QLatin1String("SELECT cookie FROM cookies"));
- sqlQuery.exec();
- while (sqlQuery.next())
- cookies.append(QNetworkCookie::parseCookies(sqlQuery.value(0).toByteArray()));
+ SQLiteStatement sqlQuery(m_database, ASCIILiteral("SELECT cookie FROM cookies"));
+ if (sqlQuery.prepare() != SQLITE_OK)
+ return;
+
+ int result = sqlQuery.step();
+ while (result == SQLITE_ROW) {
+ Vector<char> blob;
+ sqlQuery.getColumnBlobAsVector(0, blob);
+ cookies.append(QNetworkCookie::parseCookies(QByteArray::fromRawData(blob.data(), blob.size())));
+ result = sqlQuery.step();
+ }
+
+ if (result != SQLITE_DONE) {
+ LOG_ERROR("Error reading cookies from database");
+ return;
+ }
+
setAllCookies(cookies);
}
diff --git a/Source/WebCore/platform/network/qt/CookieJarQt.h b/Source/WebCore/platform/network/qt/CookieJarQt.h
index edc2813d1..0f7b6abef 100644
--- a/Source/WebCore/platform/network/qt/CookieJarQt.h
+++ b/Source/WebCore/platform/network/qt/CookieJarQt.h
@@ -21,9 +21,10 @@
#ifndef CookieJarQt_h
#define CookieJarQt_h
+#include "SQLiteDatabase.h"
+
#include <QtCore/QObject>
#include <QtNetwork/QNetworkCookieJar>
-#include <QtSql/QSqlDatabase>
#include <wtf/HashSet.h>
#include <wtf/text/WTFString.h>
@@ -47,9 +48,9 @@ public:
private:
SharedCookieJarQt(const String&);
~SharedCookieJarQt();
- void ensureDatabaseTable();
+ bool ensureDatabaseTable();
- QSqlDatabase m_database;
+ SQLiteDatabase m_database;
};
}
diff --git a/Source/WebCore/platform/win/BString.cpp b/Source/WebCore/platform/win/BString.cpp
new file mode 100644
index 000000000..8bad9c4bc
--- /dev/null
+++ b/Source/WebCore/platform/win/BString.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2006, 2007, 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 "BString.h"
+
+#include "URL.h"
+#include <windows.h>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/StringView.h>
+
+#if USE(CF)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+using namespace JSC;
+
+namespace WebCore {
+
+BString::BString()
+ : m_bstr(0)
+{
+}
+
+BString::BString(const wchar_t* characters)
+{
+ if (!characters)
+ m_bstr = 0;
+ else
+ m_bstr = SysAllocString(characters);
+}
+
+BString::BString(const wchar_t* characters, size_t length)
+{
+ if (!characters)
+ m_bstr = 0;
+ else
+ m_bstr = SysAllocStringLen(characters, length);
+}
+
+BString::BString(const String& s)
+{
+ if (s.isNull())
+ m_bstr = 0;
+ else
+ m_bstr = SysAllocStringLen(StringView(s).upconvertedCharacters(), s.length());
+}
+
+BString::BString(const URL& url)
+{
+ if (url.isNull())
+ m_bstr = 0;
+ else
+ m_bstr = SysAllocStringLen(StringView(url.string()).upconvertedCharacters(), url.string().length());
+}
+
+BString::BString(const AtomicString& s)
+{
+ if (s.isNull())
+ m_bstr = 0;
+ else
+ m_bstr = SysAllocStringLen(StringView(s.string()).upconvertedCharacters(), s.length());
+}
+
+#if USE(CF)
+BString::BString(CFStringRef cfstr)
+ : m_bstr(0)
+{
+ if (!cfstr)
+ return;
+
+ const UniChar* uniChars = CFStringGetCharactersPtr(cfstr);
+ if (uniChars) {
+ m_bstr = SysAllocStringLen((LPCWSTR)uniChars, CFStringGetLength(cfstr));
+ return;
+ }
+
+ CFIndex length = CFStringGetLength(cfstr);
+ m_bstr = SysAllocStringLen(0, length);
+ CFStringGetCharacters(cfstr, CFRangeMake(0, length), (UniChar*)m_bstr);
+ m_bstr[length] = 0;
+}
+#endif
+
+BString::~BString()
+{
+ SysFreeString(m_bstr);
+}
+
+BString::BString(const BString& other)
+{
+ if (!other.m_bstr)
+ m_bstr = 0;
+ else
+ m_bstr = SysAllocString(other.m_bstr);
+}
+
+void BString::adoptBSTR(BSTR bstr)
+{
+ SysFreeString(m_bstr);
+ m_bstr = bstr;
+}
+
+void BString::clear()
+{
+ SysFreeString(m_bstr);
+ m_bstr = 0;
+}
+
+BString& BString::operator=(const BString& other)
+{
+ if (this != &other)
+ *this = other.m_bstr;
+ return *this;
+}
+
+BString& BString::operator=(const BSTR& other)
+{
+ if (other != m_bstr) {
+ SysFreeString(m_bstr);
+ m_bstr = other ? SysAllocString(other) : 0;
+ }
+
+ return *this;
+}
+
+bool operator ==(const BString& a, const BString& b)
+{
+ if (SysStringLen((BSTR)a) != SysStringLen((BSTR)b))
+ return false;
+ if (!(BSTR)a && !(BSTR)b)
+ return true;
+ if (!(BSTR)a || !(BSTR)b)
+ return false;
+ return !wcscmp((BSTR)a, (BSTR)b);
+}
+
+bool operator !=(const BString& a, const BString& b)
+{
+ return !(a==b);
+}
+
+bool operator ==(const BString& a, BSTR b)
+{
+ if (SysStringLen((BSTR)a) != SysStringLen(b))
+ return false;
+ if (!(BSTR)a && !b)
+ return true;
+ if (!(BSTR)a || !b)
+ return false;
+ return !wcscmp((BSTR)a, b);
+}
+
+bool operator !=(const BString& a, BSTR b)
+{
+ return !(a==b);
+}
+
+bool operator ==(BSTR a, const BString& b)
+{
+ if (SysStringLen(a) != SysStringLen((BSTR)b))
+ return false;
+ if (!a && !(BSTR)b)
+ return true;
+ if (!a || !(BSTR)b)
+ return false;
+ return !wcscmp(a, (BSTR)b);
+}
+
+bool operator !=(BSTR a, const BString& b)
+{
+ return !(a==b);
+}
+
+}
diff --git a/Source/WebCore/platform/win/BString.h b/Source/WebCore/platform/win/BString.h
new file mode 100644
index 000000000..1fbe02c15
--- /dev/null
+++ b/Source/WebCore/platform/win/BString.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2006, 2007, 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 BString_h
+#define BString_h
+
+#include <wtf/Forward.h>
+
+#if USE(CF)
+typedef const struct __CFString * CFStringRef;
+#endif
+
+#ifndef _PREFAST_
+typedef wchar_t* BSTR;
+#else // _PREFAST_
+typedef _Null_terminated_ wchar_t* BSTR;
+#endif
+
+namespace WebCore {
+
+ class URL;
+
+ class BString {
+ public:
+ BString();
+ BString(const wchar_t*);
+ BString(const wchar_t*, size_t length);
+ BString(const String&);
+ BString(const AtomicString&);
+ BString(const URL&);
+#if USE(CF)
+ BString(CFStringRef);
+#endif
+ ~BString();
+
+ void adoptBSTR(BSTR);
+ void clear();
+
+ BString(const BString&);
+ BString& operator=(const BString&);
+ BString& operator=(const BSTR&);
+
+ BSTR* operator&() { ASSERT(!m_bstr); return &m_bstr; }
+ operator BSTR() const { return m_bstr; }
+
+ BSTR release() { BSTR result = m_bstr; m_bstr = 0; return result; }
+
+ private:
+ BSTR m_bstr;
+ };
+
+ bool operator ==(const BString&, const BString&);
+ bool operator !=(const BString&, const BString&);
+ bool operator ==(const BString&, BSTR);
+ bool operator !=(const BString&, BSTR);
+ bool operator ==(BSTR, const BString&);
+ bool operator !=(BSTR, const BString&);
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/win/COMPtr.h b/Source/WebCore/platform/win/COMPtr.h
new file mode 100644
index 000000000..e595edf9f
--- /dev/null
+++ b/Source/WebCore/platform/win/COMPtr.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2007, 2010 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 COMPtr_h
+#define COMPtr_h
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#include <unknwn.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashTraits.h>
+
+#ifdef __midl
+typedef LONG HRESULT;
+#else
+typedef _Return_type_success_(return >= 0) long HRESULT;
+#endif // __midl
+
+// FIXME: Should we put this into the WebCore namespace and use "using" on it
+// as we do with things in WTF?
+
+enum AdoptCOMTag { AdoptCOM };
+enum QueryTag { Query };
+enum CreateTag { Create };
+
+template<typename T> class COMPtr {
+public:
+ typedef T* PtrType;
+ COMPtr() : m_ptr(0) { }
+ COMPtr(T* ptr) : m_ptr(ptr) { if (m_ptr) m_ptr->AddRef(); }
+ COMPtr(AdoptCOMTag, T* ptr) : m_ptr(ptr) { }
+ COMPtr(const COMPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->AddRef(); }
+
+ COMPtr(QueryTag, IUnknown* ptr) : m_ptr(copyQueryInterfaceRef(ptr)) { }
+ template<typename U> COMPtr(QueryTag, const COMPtr<U>& ptr) : m_ptr(copyQueryInterfaceRef(ptr.get())) { }
+
+ COMPtr(CreateTag, const IID& clsid) : m_ptr(createInstance(clsid)) { }
+
+ // Hash table deleted values, which are only constructed and never copied or destroyed.
+ COMPtr(WTF::HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
+ bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
+
+ ~COMPtr() { if (m_ptr) m_ptr->Release(); }
+
+ T* get() const { return m_ptr; }
+
+ void clear();
+ T* leakRef();
+
+ T& operator*() const { return *m_ptr; }
+ T* operator->() const { return m_ptr; }
+
+ T** operator&() { ASSERT(!m_ptr); return &m_ptr; }
+
+ bool operator!() const { return !m_ptr; }
+
+ // This conversion operator allows implicit conversion to bool but not to other integer types.
+ typedef T* (COMPtr::*UnspecifiedBoolType)() const;
+ operator UnspecifiedBoolType() const { return m_ptr ? &COMPtr::get : 0; }
+
+ COMPtr& operator=(const COMPtr&);
+ COMPtr& operator=(T*);
+ template<typename U> COMPtr& operator=(const COMPtr<U>&);
+
+ void query(IUnknown* ptr) { adoptRef(copyQueryInterfaceRef(ptr)); }
+ template<typename U> void query(const COMPtr<U>& ptr) { query(ptr.get()); }
+
+ void create(const IID& clsid) { adoptRef(createInstance(clsid)); }
+
+ template<typename U> HRESULT copyRefTo(U**);
+ void adoptRef(T*);
+
+private:
+ static T* copyQueryInterfaceRef(IUnknown*);
+ static T* createInstance(const IID& clsid);
+ static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
+
+ T* m_ptr;
+};
+
+template<typename T> inline COMPtr<T> adoptCOM(T *ptr)
+{
+ return COMPtr<T>(AdoptCOM, ptr);
+}
+
+template<typename T> inline void COMPtr<T>::clear()
+{
+ if (T* ptr = m_ptr) {
+ m_ptr = 0;
+ ptr->Release();
+ }
+}
+
+template<typename T> inline T* COMPtr<T>::leakRef()
+{
+ T* ptr = m_ptr;
+ m_ptr = 0;
+ return ptr;
+}
+
+template<typename T> inline T* COMPtr<T>::createInstance(const IID& clsid)
+{
+ T* result;
+ if (FAILED(CoCreateInstance(clsid, 0, CLSCTX_ALL, __uuidof(result), reinterpret_cast<void**>(&result))))
+ return 0;
+ return result;
+}
+
+template<typename T> inline T* COMPtr<T>::copyQueryInterfaceRef(IUnknown* ptr)
+{
+ if (!ptr)
+ return 0;
+ T* result;
+ if (FAILED(ptr->QueryInterface(&result)))
+ return 0;
+ return result;
+}
+
+template<typename T> template<typename U> inline HRESULT COMPtr<T>::copyRefTo(U** ptr)
+{
+ if (!ptr)
+ return E_POINTER;
+ *ptr = m_ptr;
+ if (m_ptr)
+ m_ptr->AddRef();
+ return S_OK;
+}
+
+template<typename T> inline void COMPtr<T>::adoptRef(T *ptr)
+{
+ if (m_ptr)
+ m_ptr->Release();
+ m_ptr = ptr;
+}
+
+template<typename T> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<T>& o)
+{
+ T* optr = o.get();
+ if (optr)
+ optr->AddRef();
+ T* ptr = m_ptr;
+ m_ptr = optr;
+ if (ptr)
+ ptr->Release();
+ return *this;
+}
+
+template<typename T> template<typename U> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<U>& o)
+{
+ T* optr = o.get();
+ if (optr)
+ optr->AddRef();
+ T* ptr = m_ptr;
+ m_ptr = optr;
+ if (ptr)
+ ptr->Release();
+ return *this;
+}
+
+template<typename T> inline COMPtr<T>& COMPtr<T>::operator=(T* optr)
+{
+ if (optr)
+ optr->AddRef();
+ T* ptr = m_ptr;
+ m_ptr = optr;
+ if (ptr)
+ ptr->Release();
+ return *this;
+}
+
+template<typename T, typename U> inline bool operator==(const COMPtr<T>& a, const COMPtr<U>& b)
+{
+ return a.get() == b.get();
+}
+
+template<typename T, typename U> inline bool operator==(const COMPtr<T>& a, U* b)
+{
+ return a.get() == b;
+}
+
+template<typename T, typename U> inline bool operator==(T* a, const COMPtr<U>& b)
+{
+ return a == b.get();
+}
+
+template<typename T, typename U> inline bool operator!=(const COMPtr<T>& a, const COMPtr<U>& b)
+{
+ return a.get() != b.get();
+}
+
+template<typename T, typename U> inline bool operator!=(const COMPtr<T>& a, U* b)
+{
+ return a.get() != b;
+}
+
+template<typename T, typename U> inline bool operator!=(T* a, const COMPtr<U>& b)
+{
+ return a != b.get();
+}
+
+namespace WTF {
+
+template<typename P> struct IsSmartPtr<COMPtr<P>> {
+ static const bool value = true;
+};
+
+template<typename P> struct HashTraits<COMPtr<P> > : SimpleClassHashTraits<COMPtr<P>> {
+ static P* emptyValue() { return nullptr; }
+
+ typedef P* PeekType;
+ static PeekType peek(const COMPtr<P>& value) { return value.get(); }
+ static PeekType peek(P* value) { return value; }
+};
+
+template<typename P> struct DefaultHash<COMPtr<P>> {
+ typedef PtrHash<COMPtr<P>> Hash;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
new file mode 100644
index 000000000..7fdc6b8dd
--- /dev/null
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -0,0 +1,841 @@
+/*
+ * Copyright (C) 2007, 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 "ClipboardUtilitiesWin.h"
+
+#include "DocumentFragment.h"
+#include "URL.h"
+#include "TextEncoding.h"
+#include "markup.h"
+#include <shlobj.h>
+#include <shlwapi.h>
+#include <wininet.h> // for INTERNET_MAX_URL_LENGTH
+#include <wtf/StringExtras.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+
+
+#if USE(CF)
+#include <CoreFoundation/CoreFoundation.h>
+#include <wtf/RetainPtr.h>
+#endif
+
+namespace WebCore {
+
+#if USE(CF)
+FORMATETC* cfHDropFormat()
+{
+ static FORMATETC urlFormat = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &urlFormat;
+}
+
+static bool urlFromPath(CFStringRef path, String& url)
+{
+ if (!path)
+ return false;
+
+ RetainPtr<CFURLRef> cfURL = adoptCF(CFURLCreateWithFileSystemPath(0, path, kCFURLWindowsPathStyle, false));
+ if (!cfURL)
+ return false;
+
+ url = CFURLGetString(cfURL.get());
+
+ // Work around <rdar://problem/6708300>, where CFURLCreateWithFileSystemPath makes URLs with "localhost".
+ if (url.startsWith("file://localhost/"))
+ url.remove(7, 9);
+
+ return true;
+}
+#endif
+
+static bool getDataMapItem(const DragDataMap* dataObject, FORMATETC* format, String& item)
+{
+ DragDataMap::const_iterator found = dataObject->find(format->cfFormat);
+ if (found == dataObject->end())
+ return false;
+ item = found->value[0];
+ return true;
+}
+
+static bool getWebLocData(IDataObject* dataObject, String& url, String* title)
+{
+ bool succeeded = false;
+#if USE(CF)
+ WCHAR filename[MAX_PATH];
+ WCHAR urlBuffer[INTERNET_MAX_URL_LENGTH];
+
+ STGMEDIUM medium;
+ if (FAILED(dataObject->GetData(cfHDropFormat(), &medium)))
+ return false;
+
+ HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal));
+
+ if (!hdrop)
+ return false;
+
+ if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename)))
+ goto exit;
+
+ if (_wcsicmp(PathFindExtensionW(filename), L".url"))
+ goto exit;
+
+ if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, WTF_ARRAY_LENGTH(urlBuffer), filename))
+ goto exit;
+
+ if (title) {
+ PathRemoveExtension(filename);
+ *title = String((UChar*)filename);
+ }
+
+ url = String((UChar*)urlBuffer);
+ succeeded = true;
+
+exit:
+ // Free up memory.
+ DragFinish(hdrop);
+ GlobalUnlock(medium.hGlobal);
+#endif
+ return succeeded;
+}
+
+static bool getWebLocData(const DragDataMap* dataObject, String& url, String* title)
+{
+#if USE(CF)
+ WCHAR filename[MAX_PATH];
+ WCHAR urlBuffer[INTERNET_MAX_URL_LENGTH];
+
+ if (!dataObject->contains(cfHDropFormat()->cfFormat))
+ return false;
+
+ wcscpy(filename, dataObject->get(cfHDropFormat()->cfFormat)[0].charactersWithNullTermination().data());
+ if (_wcsicmp(PathFindExtensionW(filename), L".url"))
+ return false;
+
+ if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, WTF_ARRAY_LENGTH(urlBuffer), filename))
+ return false;
+
+ if (title) {
+ PathRemoveExtension(filename);
+ *title = filename;
+ }
+
+ url = urlBuffer;
+ return true;
+#else
+ return false;
+#endif
+}
+
+static String extractURL(const String &inURL, String* title)
+{
+ String url = inURL;
+ int splitLoc = url.find('\n');
+ if (splitLoc > 0) {
+ if (title)
+ *title = url.substring(splitLoc+1);
+ url.truncate(splitLoc);
+ } else if (title)
+ *title = url;
+ return url;
+}
+
+// Firefox text/html
+static FORMATETC* texthtmlFormat()
+{
+ static UINT cf = RegisterClipboardFormat(L"text/html");
+ static FORMATETC texthtmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &texthtmlFormat;
+}
+
+HGLOBAL createGlobalData(const URL& url, const String& title)
+{
+ String mutableURL(url.string());
+ String mutableTitle(title);
+ SIZE_T size = mutableURL.length() + mutableTitle.length() + 2; // +1 for "\n" and +1 for null terminator
+ HGLOBAL cbData = ::GlobalAlloc(GPTR, size * sizeof(UChar));
+
+ if (cbData) {
+ PWSTR buffer = static_cast<PWSTR>(GlobalLock(cbData));
+ _snwprintf(buffer, size, L"%s\n%s", mutableURL.charactersWithNullTermination().data(), mutableTitle.charactersWithNullTermination().data());
+ GlobalUnlock(cbData);
+ }
+ return cbData;
+}
+
+HGLOBAL createGlobalData(const String& str)
+{
+ HGLOBAL vm = ::GlobalAlloc(GPTR, (str.length() + 1) * sizeof(UChar));
+ if (!vm)
+ return 0;
+ UChar* buffer = static_cast<UChar*>(GlobalLock(vm));
+ StringView(str).getCharactersWithUpconvert(buffer);
+ buffer[str.length()] = 0;
+ GlobalUnlock(vm);
+ return vm;
+}
+
+HGLOBAL createGlobalData(const Vector<char>& vector)
+{
+ HGLOBAL vm = ::GlobalAlloc(GPTR, vector.size() + 1);
+ if (!vm)
+ return 0;
+ char* buffer = static_cast<char*>(GlobalLock(vm));
+ memcpy(buffer, vector.data(), vector.size());
+ buffer[vector.size()] = 0;
+ GlobalUnlock(vm);
+ return vm;
+}
+
+static String getFullCFHTML(IDataObject* data)
+{
+ STGMEDIUM store;
+ if (SUCCEEDED(data->GetData(htmlFormat(), &store))) {
+ // MS HTML Format parsing
+ char* data = static_cast<char*>(GlobalLock(store.hGlobal));
+ SIZE_T dataSize = ::GlobalSize(store.hGlobal);
+ String cfhtml(UTF8Encoding().decode(data, dataSize));
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ return cfhtml;
+ }
+ return String();
+}
+
+static void append(Vector<char>& vector, const char* string)
+{
+ vector.append(string, strlen(string));
+}
+
+static void append(Vector<char>& vector, const CString& string)
+{
+ vector.append(string.data(), string.length());
+}
+
+// Find the markup between "<!--StartFragment -->" and "<!--EndFragment -->", accounting for browser quirks.
+static String extractMarkupFromCFHTML(const String& cfhtml)
+{
+ unsigned markupStart = cfhtml.find("<html", 0, false);
+ unsigned tagStart = cfhtml.find("startfragment", markupStart, false);
+ unsigned fragmentStart = cfhtml.find('>', tagStart) + 1;
+ unsigned tagEnd = cfhtml.find("endfragment", fragmentStart, false);
+ unsigned fragmentEnd = cfhtml.reverseFind('<', tagEnd);
+ return cfhtml.substring(fragmentStart, fragmentEnd - fragmentStart).stripWhiteSpace();
+}
+
+// Documentation for the CF_HTML format is available at http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp
+void markupToCFHTML(const String& markup, const String& srcURL, Vector<char>& result)
+{
+ if (markup.isEmpty())
+ return;
+
+ #define MAX_DIGITS 10
+ #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits)
+ #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u"
+ #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS)
+
+ const char* header = "Version:0.9\n"
+ "StartHTML:" NUMBER_FORMAT "\n"
+ "EndHTML:" NUMBER_FORMAT "\n"
+ "StartFragment:" NUMBER_FORMAT "\n"
+ "EndFragment:" NUMBER_FORMAT "\n";
+ const char* sourceURLPrefix = "SourceURL:";
+
+ const char* startMarkup = "<HTML>\n<BODY>\n<!--StartFragment-->\n";
+ const char* endMarkup = "\n<!--EndFragment-->\n</BODY>\n</HTML>";
+
+ CString sourceURLUTF8 = srcURL == blankURL() ? "" : srcURL.utf8();
+ CString markupUTF8 = markup.utf8();
+
+ // calculate offsets
+ unsigned startHTMLOffset = strlen(header) - strlen(NUMBER_FORMAT) * 4 + MAX_DIGITS * 4;
+ if (sourceURLUTF8.length())
+ startHTMLOffset += strlen(sourceURLPrefix) + sourceURLUTF8.length() + 1;
+ unsigned startFragmentOffset = startHTMLOffset + strlen(startMarkup);
+ unsigned endFragmentOffset = startFragmentOffset + markupUTF8.length();
+ unsigned endHTMLOffset = endFragmentOffset + strlen(endMarkup);
+
+ unsigned headerBufferLength = startHTMLOffset + 1; // + 1 for '\0' terminator.
+ char* headerBuffer = (char*)malloc(headerBufferLength);
+ snprintf(headerBuffer, headerBufferLength, header, startHTMLOffset, endHTMLOffset, startFragmentOffset, endFragmentOffset);
+ append(result, CString(headerBuffer));
+ free(headerBuffer);
+ if (sourceURLUTF8.length()) {
+ append(result, sourceURLPrefix);
+ append(result, sourceURLUTF8);
+ result.append('\n');
+ }
+ append(result, startMarkup);
+ append(result, markupUTF8);
+ append(result, endMarkup);
+
+ #undef MAX_DIGITS
+ #undef MAKE_NUMBER_FORMAT_1
+ #undef MAKE_NUMBER_FORMAT_2
+ #undef NUMBER_FORMAT
+}
+
+void replaceNewlinesWithWindowsStyleNewlines(String& str)
+{
+ DEPRECATED_DEFINE_STATIC_LOCAL(String, windowsNewline, (ASCIILiteral("\r\n")));
+ StringBuilder result;
+ for (unsigned index = 0; index < str.length(); ++index) {
+ if (str[index] != '\n' || (index > 0 && str[index - 1] == '\r'))
+ result.append(str[index]);
+ else
+ result.append(windowsNewline);
+ }
+ str = result.toString();
+}
+
+void replaceNBSPWithSpace(String& str)
+{
+ static const UChar NonBreakingSpaceCharacter = 0xA0;
+ static const UChar SpaceCharacter = ' ';
+ str.replace(NonBreakingSpaceCharacter, SpaceCharacter);
+}
+
+FORMATETC* urlWFormat()
+{
+ static UINT cf = RegisterClipboardFormat(L"UniformResourceLocatorW");
+ static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &urlFormat;
+}
+
+FORMATETC* urlFormat()
+{
+ static UINT cf = RegisterClipboardFormat(L"UniformResourceLocator");
+ static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &urlFormat;
+}
+
+FORMATETC* plainTextFormat()
+{
+ static FORMATETC textFormat = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &textFormat;
+}
+
+FORMATETC* plainTextWFormat()
+{
+ static FORMATETC textFormat = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &textFormat;
+}
+
+FORMATETC* filenameWFormat()
+{
+ static UINT cf = RegisterClipboardFormat(L"FileNameW");
+ static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &urlFormat;
+}
+
+FORMATETC* filenameFormat()
+{
+ static UINT cf = RegisterClipboardFormat(L"FileName");
+ static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &urlFormat;
+}
+
+// MSIE HTML Format
+FORMATETC* htmlFormat()
+{
+ static UINT cf = RegisterClipboardFormat(L"HTML Format");
+ static FORMATETC htmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &htmlFormat;
+}
+
+FORMATETC* smartPasteFormat()
+{
+ static UINT cf = RegisterClipboardFormat(L"WebKit Smart Paste Format");
+ static FORMATETC htmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
+ return &htmlFormat;
+}
+
+FORMATETC* fileDescriptorFormat()
+{
+ static UINT cf = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
+ static FORMATETC fileDescriptorFormat = { cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ return &fileDescriptorFormat;
+}
+
+FORMATETC* fileContentFormatZero()
+{
+ static UINT cf = RegisterClipboardFormat(CFSTR_FILECONTENTS);
+ static FORMATETC fileContentFormat = { cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL };
+ return &fileContentFormat;
+}
+
+void getFileDescriptorData(IDataObject* dataObject, int& size, String& pathname)
+{
+ STGMEDIUM store;
+ size = 0;
+ if (FAILED(dataObject->GetData(fileDescriptorFormat(), &store)))
+ return;
+
+ FILEGROUPDESCRIPTOR* fgd = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(store.hGlobal));
+ size = fgd->fgd[0].nFileSizeLow;
+ pathname = fgd->fgd[0].cFileName;
+
+ GlobalUnlock(store.hGlobal);
+ ::ReleaseStgMedium(&store);
+}
+
+void getFileContentData(IDataObject* dataObject, int size, void* dataBlob)
+{
+ STGMEDIUM store;
+ if (FAILED(dataObject->GetData(fileContentFormatZero(), &store)))
+ return;
+ void* data = GlobalLock(store.hGlobal);
+ ::CopyMemory(dataBlob, data, size);
+
+ GlobalUnlock(store.hGlobal);
+ ::ReleaseStgMedium(&store);
+}
+
+void setFileDescriptorData(IDataObject* dataObject, int size, const String& passedPathname)
+{
+ String pathname = passedPathname;
+
+ STGMEDIUM medium = { 0 };
+ medium.tymed = TYMED_HGLOBAL;
+
+ medium.hGlobal = ::GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
+ if (!medium.hGlobal)
+ return;
+
+ FILEGROUPDESCRIPTOR* fgd = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(medium.hGlobal));
+ ::ZeroMemory(fgd, sizeof(FILEGROUPDESCRIPTOR));
+ fgd->cItems = 1;
+ fgd->fgd[0].dwFlags = FD_FILESIZE;
+ fgd->fgd[0].nFileSizeLow = size;
+
+ int maxSize = std::min<int>(pathname.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
+ CopyMemory(fgd->fgd[0].cFileName, pathname.charactersWithNullTermination().data(), maxSize * sizeof(UChar));
+ GlobalUnlock(medium.hGlobal);
+
+ dataObject->SetData(fileDescriptorFormat(), &medium, TRUE);
+}
+
+void setFileContentData(IDataObject* dataObject, int size, void* dataBlob)
+{
+ STGMEDIUM medium = { 0 };
+ medium.tymed = TYMED_HGLOBAL;
+
+ medium.hGlobal = ::GlobalAlloc(GPTR, size);
+ if (!medium.hGlobal)
+ return;
+ void* fileContents = GlobalLock(medium.hGlobal);
+ ::CopyMemory(fileContents, dataBlob, size);
+ GlobalUnlock(medium.hGlobal);
+
+ dataObject->SetData(fileContentFormatZero(), &medium, TRUE);
+}
+
+String getURL(IDataObject* dataObject, DragData::FilenameConversionPolicy filenamePolicy, String* title)
+{
+ STGMEDIUM store;
+ String url;
+ if (getWebLocData(dataObject, url, title))
+ return url;
+
+ if (SUCCEEDED(dataObject->GetData(urlWFormat(), &store))) {
+ // URL using Unicode
+ UChar* data = static_cast<UChar*>(GlobalLock(store.hGlobal));
+ url = extractURL(String(data), title);
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ } else if (SUCCEEDED(dataObject->GetData(urlFormat(), &store))) {
+ // URL using ASCII
+ char* data = static_cast<char*>(GlobalLock(store.hGlobal));
+ url = extractURL(String(data), title);
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ }
+#if USE(CF)
+ else if (filenamePolicy == DragData::ConvertFilenames) {
+ if (SUCCEEDED(dataObject->GetData(filenameWFormat(), &store))) {
+ // file using unicode
+ wchar_t* data = static_cast<wchar_t*>(GlobalLock(store.hGlobal));
+ if (data && data[0] && (PathFileExists(data) || PathIsUNC(data))) {
+ RetainPtr<CFStringRef> pathAsCFString = adoptCF(CFStringCreateWithCharacters(kCFAllocatorDefault, (const UniChar*)data, wcslen(data)));
+ if (urlFromPath(pathAsCFString.get(), url) && title)
+ *title = url;
+ }
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ } else if (SUCCEEDED(dataObject->GetData(filenameFormat(), &store))) {
+ // filename using ascii
+ char* data = static_cast<char*>(GlobalLock(store.hGlobal));
+ if (data && data[0] && (PathFileExistsA(data) || PathIsUNCA(data))) {
+ RetainPtr<CFStringRef> pathAsCFString = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, data, kCFStringEncodingASCII));
+ if (urlFromPath(pathAsCFString.get(), url) && title)
+ *title = url;
+ }
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ }
+ }
+#endif
+ return url;
+}
+
+String getURL(const DragDataMap* data, DragData::FilenameConversionPolicy filenamePolicy, String* title)
+{
+ String url;
+
+ if (getWebLocData(data, url, title))
+ return url;
+ if (getDataMapItem(data, urlWFormat(), url))
+ return extractURL(url, title);
+ if (getDataMapItem(data, urlFormat(), url))
+ return extractURL(url, title);
+#if USE(CF)
+ if (filenamePolicy != DragData::ConvertFilenames)
+ return url;
+
+ String stringData;
+ if (!getDataMapItem(data, filenameWFormat(), stringData))
+ getDataMapItem(data, filenameFormat(), stringData);
+
+ if (stringData.isEmpty() || (!PathFileExists(stringData.charactersWithNullTermination().data()) && !PathIsUNC(stringData.charactersWithNullTermination().data())))
+ return url;
+ RetainPtr<CFStringRef> pathAsCFString = adoptCF(CFStringCreateWithCharacters(kCFAllocatorDefault, (const UniChar *)stringData.charactersWithNullTermination().data(), wcslen(stringData.charactersWithNullTermination().data())));
+ if (urlFromPath(pathAsCFString.get(), url) && title)
+ *title = url;
+#endif
+ return url;
+}
+
+String getPlainText(IDataObject* dataObject)
+{
+ STGMEDIUM store;
+ String text;
+ if (SUCCEEDED(dataObject->GetData(plainTextWFormat(), &store))) {
+ // Unicode text
+ UChar* data = static_cast<UChar*>(GlobalLock(store.hGlobal));
+ text = String(data);
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ } else if (SUCCEEDED(dataObject->GetData(plainTextFormat(), &store))) {
+ // ASCII text
+ char* data = static_cast<char*>(GlobalLock(store.hGlobal));
+ text = String(data);
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ } else {
+ // FIXME: Originally, we called getURL() here because dragging and dropping files doesn't
+ // populate the drag with text data. Per https://bugs.webkit.org/show_bug.cgi?id=38826, this
+ // is undesirable, so maybe this line can be removed.
+ text = getURL(dataObject, DragData::DoNotConvertFilenames);
+ }
+ return text;
+}
+
+String getPlainText(const DragDataMap* data)
+{
+ String text;
+
+ if (getDataMapItem(data, plainTextWFormat(), text))
+ return text;
+ if (getDataMapItem(data, plainTextFormat(), text))
+ return text;
+ return getURL(data, DragData::DoNotConvertFilenames);
+}
+
+String getTextHTML(IDataObject* data)
+{
+ STGMEDIUM store;
+ String html;
+ if (SUCCEEDED(data->GetData(texthtmlFormat(), &store))) {
+ UChar* data = static_cast<UChar*>(GlobalLock(store.hGlobal));
+ html = String(data);
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ }
+ return html;
+}
+
+String getTextHTML(const DragDataMap* data)
+{
+ String text;
+ getDataMapItem(data, texthtmlFormat(), text);
+ return text;
+}
+
+String getCFHTML(IDataObject* data)
+{
+ String cfhtml = getFullCFHTML(data);
+ if (!cfhtml.isEmpty())
+ return extractMarkupFromCFHTML(cfhtml);
+ return String();
+}
+
+String getCFHTML(const DragDataMap* dataMap)
+{
+ String cfhtml;
+ getDataMapItem(dataMap, htmlFormat(), cfhtml);
+ return extractMarkupFromCFHTML(cfhtml);
+}
+
+PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*)
+{
+ // FIXME: We should be able to create fragments from files
+ return 0;
+}
+
+PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const DragDataMap*)
+{
+ // FIXME: We should be able to create fragments from files
+ return 0;
+}
+
+bool containsFilenames(const IDataObject*)
+{
+ // FIXME: We'll want to update this once we can produce fragments from files
+ return false;
+}
+
+bool containsFilenames(const DragDataMap*)
+{
+ // FIXME: We'll want to update this once we can produce fragments from files
+ return false;
+}
+
+// Convert a String containing CF_HTML formatted text to a DocumentFragment
+PassRefPtr<DocumentFragment> fragmentFromCFHTML(Document* doc, const String& cfhtml)
+{
+ // obtain baseURL if present
+ String srcURLStr("sourceURL:");
+ String srcURL;
+ unsigned lineStart = cfhtml.find(srcURLStr, 0, false);
+ if (lineStart != -1) {
+ unsigned srcEnd = cfhtml.find("\n", lineStart, false);
+ unsigned srcStart = lineStart+srcURLStr.length();
+ String rawSrcURL = cfhtml.substring(srcStart, srcEnd-srcStart);
+ replaceNBSPWithSpace(rawSrcURL);
+ srcURL = rawSrcURL.stripWhiteSpace();
+ }
+
+ String markup = extractMarkupFromCFHTML(cfhtml);
+ return createFragmentFromMarkup(*doc, markup, srcURL, DisallowScriptingAndPluginContent);
+}
+
+PassRefPtr<DocumentFragment> fragmentFromHTML(Document* doc, IDataObject* data)
+{
+ if (!doc || !data)
+ return 0;
+
+ String cfhtml = getFullCFHTML(data);
+ if (!cfhtml.isEmpty()) {
+ if (RefPtr<DocumentFragment> fragment = fragmentFromCFHTML(doc, cfhtml))
+ return fragment.release();
+ }
+
+ String html = getTextHTML(data);
+ String srcURL;
+ if (!html.isEmpty())
+ return createFragmentFromMarkup(*doc, html, srcURL, DisallowScriptingAndPluginContent);
+
+ return 0;
+}
+
+PassRefPtr<DocumentFragment> fragmentFromHTML(Document* document, const DragDataMap* data)
+{
+ if (!document || !data || data->isEmpty())
+ return 0;
+
+ String stringData;
+ if (getDataMapItem(data, htmlFormat(), stringData)) {
+ if (RefPtr<DocumentFragment> fragment = fragmentFromCFHTML(document, stringData))
+ return fragment.release();
+ }
+
+ String srcURL;
+ if (getDataMapItem(data, texthtmlFormat(), stringData))
+ return createFragmentFromMarkup(*document, stringData, srcURL, DisallowScriptingAndPluginContent);
+
+ return 0;
+}
+
+bool containsHTML(IDataObject* data)
+{
+ return SUCCEEDED(data->QueryGetData(texthtmlFormat())) || SUCCEEDED(data->QueryGetData(htmlFormat()));
+}
+
+bool containsHTML(const DragDataMap* data)
+{
+ return data->contains(texthtmlFormat()->cfFormat) || data->contains(htmlFormat()->cfFormat);
+}
+
+typedef void (*GetStringFunction)(IDataObject*, FORMATETC*, Vector<String>&);
+typedef void (*SetStringFunction)(IDataObject*, FORMATETC*, const Vector<String>&);
+
+struct ClipboardDataItem {
+ GetStringFunction getString;
+ SetStringFunction setString;
+ FORMATETC* format;
+
+ ClipboardDataItem(FORMATETC* format, GetStringFunction getString, SetStringFunction setString): format(format), getString(getString), setString(setString) { }
+};
+
+typedef HashMap<UINT, ClipboardDataItem*> ClipboardFormatMap;
+
+// Getter functions.
+
+template<typename T> void getStringData(IDataObject* data, FORMATETC* format, Vector<String>& dataStrings)
+{
+ STGMEDIUM store;
+ if (FAILED(data->GetData(format, &store)))
+ return;
+ dataStrings.append(String(static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T)));
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+}
+
+void getUtf8Data(IDataObject* data, FORMATETC* format, Vector<String>& dataStrings)
+{
+ STGMEDIUM store;
+ if (FAILED(data->GetData(format, &store)))
+ return;
+ dataStrings.append(String(UTF8Encoding().decode(static_cast<char*>(GlobalLock(store.hGlobal)), GlobalSize(store.hGlobal))));
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+}
+
+#if USE(CF)
+void getCFData(IDataObject* data, FORMATETC* format, Vector<String>& dataStrings)
+{
+ STGMEDIUM store;
+ if (FAILED(data->GetData(format, &store)))
+ return;
+
+ HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(store.hGlobal));
+ if (!hdrop)
+ return;
+
+ WCHAR filename[MAX_PATH];
+ UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
+ for (UINT i = 0; i < fileCount; i++) {
+ if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
+ continue;
+ dataStrings.append(static_cast<UChar*>(filename));
+ }
+
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+}
+#endif
+
+// Setter functions.
+
+void setUCharData(IDataObject* data, FORMATETC* format, const Vector<String>& dataStrings)
+{
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ medium.hGlobal = createGlobalData(dataStrings.first());
+ if (!medium.hGlobal)
+ return;
+ data->SetData(format, &medium, FALSE);
+ ::GlobalFree(medium.hGlobal);
+}
+
+void setUtf8Data(IDataObject* data, FORMATETC* format, const Vector<String>& dataStrings)
+{
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ CString charString = dataStrings.first().utf8();
+ size_t stringLength = charString.length();
+ medium.hGlobal = ::GlobalAlloc(GPTR, stringLength + 1);
+ if (!medium.hGlobal)
+ return;
+ char* buffer = static_cast<char*>(GlobalLock(medium.hGlobal));
+ memcpy(buffer, charString.data(), stringLength);
+ buffer[stringLength] = 0;
+ GlobalUnlock(medium.hGlobal);
+ data->SetData(format, &medium, FALSE);
+ ::GlobalFree(medium.hGlobal);
+}
+
+#if USE(CF)
+void setCFData(IDataObject* data, FORMATETC* format, const Vector<String>& dataStrings)
+{
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (dataStrings.first().length() + 2));
+ medium.hGlobal = ::GlobalAlloc(GHND | GMEM_SHARE, dropFilesSize);
+ if (!medium.hGlobal)
+ return;
+
+ DROPFILES* dropFiles = reinterpret_cast<DROPFILES *>(GlobalLock(medium.hGlobal));
+ dropFiles->pFiles = sizeof(DROPFILES);
+ dropFiles->fWide = TRUE;
+ String filename = dataStrings.first();
+ wcscpy(reinterpret_cast<LPWSTR>(dropFiles + 1), filename.charactersWithNullTermination().data());
+ GlobalUnlock(medium.hGlobal);
+ data->SetData(format, &medium, FALSE);
+ ::GlobalFree(medium.hGlobal);
+}
+#endif
+
+static const ClipboardFormatMap& getClipboardMap()
+{
+ static ClipboardFormatMap formatMap;
+ if (formatMap.isEmpty()) {
+ formatMap.add(htmlFormat()->cfFormat, new ClipboardDataItem(htmlFormat(), getUtf8Data, setUtf8Data));
+ formatMap.add(texthtmlFormat()->cfFormat, new ClipboardDataItem(texthtmlFormat(), getStringData<UChar>, setUCharData));
+ formatMap.add(plainTextFormat()->cfFormat, new ClipboardDataItem(plainTextFormat(), getStringData<char>, setUtf8Data));
+ formatMap.add(plainTextWFormat()->cfFormat, new ClipboardDataItem(plainTextWFormat(), getStringData<UChar>, setUCharData));
+#if USE(CF)
+ formatMap.add(cfHDropFormat()->cfFormat, new ClipboardDataItem(cfHDropFormat(), getCFData, setCFData));
+#endif
+ formatMap.add(filenameFormat()->cfFormat, new ClipboardDataItem(filenameFormat(), getStringData<char>, setUtf8Data));
+ formatMap.add(filenameWFormat()->cfFormat, new ClipboardDataItem(filenameWFormat(), getStringData<UChar>, setUCharData));
+ formatMap.add(urlFormat()->cfFormat, new ClipboardDataItem(urlFormat(), getStringData<char>, setUtf8Data));
+ formatMap.add(urlWFormat()->cfFormat, new ClipboardDataItem(urlWFormat(), getStringData<UChar>, setUCharData));
+ }
+ return formatMap;
+}
+
+void getClipboardData(IDataObject* dataObject, FORMATETC* format, Vector<String>& dataStrings)
+{
+ const ClipboardFormatMap& formatMap = getClipboardMap();
+ ClipboardFormatMap::const_iterator found = formatMap.find(format->cfFormat);
+ if (found == formatMap.end())
+ return;
+ found->value->getString(dataObject, found->value->format, dataStrings);
+}
+
+void setClipboardData(IDataObject* dataObject, UINT format, const Vector<String>& dataStrings)
+{
+ const ClipboardFormatMap& formatMap = getClipboardMap();
+ ClipboardFormatMap::const_iterator found = formatMap.find(format);
+ if (found == formatMap.end())
+ return;
+ found->value->setString(dataObject, found->value->format, dataStrings);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
new file mode 100644
index 000000000..c2f16d78d
--- /dev/null
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h
@@ -0,0 +1,89 @@
+/*
+ * 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 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 ClipboardUtilitiesWin_h
+#define ClipboardUtilitiesWin_h
+
+#include "DragData.h"
+#include <windows.h>
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class Document;
+class DocumentFragment;
+class URL;
+
+HGLOBAL createGlobalData(const String&);
+HGLOBAL createGlobalData(const Vector<char>&);
+HGLOBAL createGlobalData(const URL& url, const String& title);
+
+FORMATETC* urlWFormat();
+FORMATETC* urlFormat();
+FORMATETC* plainTextWFormat();
+FORMATETC* plainTextFormat();
+FORMATETC* filenameWFormat();
+FORMATETC* filenameFormat();
+FORMATETC* htmlFormat();
+FORMATETC* cfHDropFormat();
+FORMATETC* smartPasteFormat();
+FORMATETC* fileDescriptorFormat();
+FORMATETC* fileContentFormatZero();
+
+void markupToCFHTML(const String& markup, const String& srcURL, Vector<char>& result);
+
+void replaceNewlinesWithWindowsStyleNewlines(String&);
+void replaceNBSPWithSpace(String&);
+
+bool containsFilenames(const IDataObject*);
+bool containsFilenames(const DragDataMap*);
+bool containsHTML(IDataObject*);
+bool containsHTML(const DragDataMap*);
+
+PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*);
+PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const DragDataMap*);
+PassRefPtr<DocumentFragment> fragmentFromHTML(Document*, IDataObject*);
+PassRefPtr<DocumentFragment> fragmentFromHTML(Document*, const DragDataMap*);
+PassRefPtr<DocumentFragment> fragmentFromCFHTML(Document*, const String& cfhtml);
+
+String getURL(IDataObject*, DragData::FilenameConversionPolicy, String* title = 0);
+String getURL(const DragDataMap*, DragData::FilenameConversionPolicy, String* title = 0);
+String getPlainText(IDataObject*);
+String getPlainText(const DragDataMap*);
+String getTextHTML(IDataObject*);
+String getTextHTML(const DragDataMap*);
+String getCFHTML(IDataObject*);
+String getCFHTML(const DragDataMap*);
+
+void getClipboardData(IDataObject*, FORMATETC* fetc, Vector<String>& dataStrings);
+void setClipboardData(IDataObject*, UINT format, const Vector<String>& dataStrings);
+void getFileDescriptorData(IDataObject*, int& size, String& pathname);
+void getFileContentData(IDataObject*, int size, void* dataBlob);
+void setFileDescriptorData(IDataObject*, int size, const String& pathname);
+void setFileContentData(IDataObject*, int size, void* dataBlob);
+
+} // namespace WebCore
+
+#endif // ClipboardUtilitiesWin_h
diff --git a/Source/WebCore/platform/win/CursorWin.cpp b/Source/WebCore/platform/win/CursorWin.cpp
new file mode 100644
index 000000000..38811fc10
--- /dev/null
+++ b/Source/WebCore/platform/win/CursorWin.cpp
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
+ * Copyright (C) 2006, 2007, 2008, 2013 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 "Cursor.h"
+
+#include "BitmapInfo.h"
+#include "HWndDC.h"
+#include "Image.h"
+#include "IntPoint.h"
+#include "SystemInfo.h"
+#include <wtf/win/GDIObject.h>
+
+#include <windows.h>
+
+#define ALPHA_CURSORS
+
+namespace WebCore {
+
+static PassRefPtr<SharedCursor> createSharedCursor(Image* img, const IntPoint& hotSpot)
+{
+ RefPtr<SharedCursor> impl;
+
+ IntPoint effectiveHotSpot = determineHotSpot(img, hotSpot);
+ static bool doAlpha = windowsVersion() >= WindowsXP;
+ BitmapInfo cursorImage = BitmapInfo::create(IntSize(img->width(), img->height()));
+
+ HWndDC dc(0);
+ auto workingDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ if (doAlpha) {
+ auto hCursor = adoptGDIObject(::CreateDIBSection(dc, &cursorImage, DIB_RGB_COLORS, nullptr, 0, 0));
+ if (!hCursor)
+ return nullptr;
+
+ img->getHBITMAP(hCursor.get());
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(workingDC.get(), hCursor.get());
+ SetBkMode(workingDC.get(), TRANSPARENT);
+ SelectObject(workingDC.get(), hOldBitmap);
+
+ Vector<unsigned char, 128> maskBits;
+ maskBits.fill(0xff, (img->width() + 7) / 8 * img->height());
+ auto hMask = adoptGDIObject(::CreateBitmap(img->width(), img->height(), 1, 1, maskBits.data()));
+
+ ICONINFO ii;
+ ii.fIcon = FALSE;
+ ii.xHotspot = effectiveHotSpot.x();
+ ii.yHotspot = effectiveHotSpot.y();
+ ii.hbmMask = hMask.get();
+ ii.hbmColor = hCursor.get();
+
+ impl = SharedCursor::create(::CreateIconIndirect(&ii));
+ } else {
+ // Platform doesn't support alpha blended cursors, so we need
+ // to create the mask manually
+ auto andMaskDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ auto xorMaskDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ auto hCursor = adoptGDIObject(::CreateDIBSection(dc, &cursorImage, DIB_RGB_COLORS, nullptr, 0, 0));
+ if (!hCursor)
+ return nullptr;
+
+ img->getHBITMAP(hCursor.get());
+ BITMAP cursor;
+ GetObject(hCursor.get(), sizeof(BITMAP), &cursor);
+ auto andMask = adoptGDIObject(::CreateBitmap(cursor.bmWidth, cursor.bmHeight, 1, 1, 0));
+ auto xorMask = adoptGDIObject(::CreateCompatibleBitmap(dc, cursor.bmWidth, cursor.bmHeight));
+ HBITMAP oldCursor = (HBITMAP)SelectObject(workingDC.get(), hCursor.get());
+ HBITMAP oldAndMask = (HBITMAP)SelectObject(andMaskDC.get(), andMask.get());
+ HBITMAP oldXorMask = (HBITMAP)SelectObject(xorMaskDC.get(), xorMask.get());
+
+ SetBkColor(workingDC.get(), RGB(0, 0, 0));
+ BitBlt(andMaskDC.get(), 0, 0, cursor.bmWidth, cursor.bmHeight, workingDC.get(), 0, 0, SRCCOPY);
+
+ SetBkColor(xorMaskDC.get(), RGB(255, 255, 255));
+ SetTextColor(xorMaskDC.get(), RGB(255, 255, 255));
+ BitBlt(xorMaskDC.get(), 0, 0, cursor.bmWidth, cursor.bmHeight, andMaskDC.get(), 0, 0, SRCCOPY);
+ BitBlt(xorMaskDC.get(), 0, 0, cursor.bmWidth, cursor.bmHeight, workingDC.get(), 0, 0, SRCAND);
+
+ SelectObject(workingDC.get(), oldCursor);
+ SelectObject(andMaskDC.get(), oldAndMask);
+ SelectObject(xorMaskDC.get(), oldXorMask);
+
+ ICONINFO icon = {0};
+ icon.fIcon = FALSE;
+ icon.xHotspot = effectiveHotSpot.x();
+ icon.yHotspot = effectiveHotSpot.y();
+ icon.hbmMask = andMask.get();
+ icon.hbmColor = xorMask.get();
+ impl = SharedCursor::create(CreateIconIndirect(&icon));
+ }
+
+ return impl.release();
+}
+
+static PassRefPtr<SharedCursor> loadSharedCursor(HINSTANCE hInstance, LPCWSTR lpCursorName)
+{
+ return SharedCursor::create(::LoadCursorW(hInstance, lpCursorName));
+}
+
+static PassRefPtr<SharedCursor> loadCursorByName(char* name, int x, int y)
+{
+ IntPoint hotSpot(x, y);
+ RefPtr<Image> cursorImage(Image::loadPlatformResource(name));
+ if (cursorImage && !cursorImage->isNull())
+ return createSharedCursor(cursorImage.get(), hotSpot);
+ return loadSharedCursor(0, IDC_ARROW);
+}
+
+void Cursor::ensurePlatformCursor() const
+{
+ if (m_platformCursor)
+ return;
+
+ switch (m_type) {
+ case Cursor::Pointer:
+ case Cursor::Cell:
+ case Cursor::ContextMenu:
+ case Cursor::Alias:
+ case Cursor::Copy:
+ case Cursor::None:
+ case Cursor::Grab:
+ case Cursor::Grabbing:
+ m_platformCursor = loadSharedCursor(0, IDC_ARROW);
+ break;
+ case Cursor::Cross:
+ m_platformCursor = loadSharedCursor(0, IDC_CROSS);
+ break;
+ case Cursor::Hand:
+ m_platformCursor = loadSharedCursor(0, IDC_HAND);
+ break;
+ case Cursor::IBeam:
+ m_platformCursor = loadSharedCursor(0, IDC_IBEAM);
+ break;
+ case Cursor::Wait:
+ m_platformCursor = loadSharedCursor(0, IDC_WAIT);
+ break;
+ case Cursor::Help:
+ m_platformCursor = loadSharedCursor(0, IDC_HELP);
+ break;
+ case Cursor::Move:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEALL);
+ break;
+ case Cursor::MiddlePanning:
+ m_platformCursor = loadCursorByName("panIcon", 8, 8);
+ break;
+ case Cursor::EastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::EastPanning:
+ m_platformCursor = loadCursorByName("panEastCursor", 7, 7);
+ break;
+ case Cursor::NorthResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::NorthPanning:
+ m_platformCursor = loadCursorByName("panNorthCursor", 7, 7);
+ break;
+ case Cursor::NorthEastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENESW);
+ break;
+ case Cursor::NorthEastPanning:
+ m_platformCursor = loadCursorByName("panNorthEastCursor", 7, 7);
+ break;
+ case Cursor::NorthWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENWSE);
+ break;
+ case Cursor::NorthWestPanning:
+ m_platformCursor = loadCursorByName("panNorthWestCursor", 7, 7);
+ break;
+ case Cursor::SouthResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::SouthPanning:
+ m_platformCursor = loadCursorByName("panSouthCursor", 7, 7);
+ break;
+ case Cursor::SouthEastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENWSE);
+ break;
+ case Cursor::SouthEastPanning:
+ m_platformCursor = loadCursorByName("panSouthEastCursor", 7, 7);
+ break;
+ case Cursor::SouthWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENESW);
+ break;
+ case Cursor::SouthWestPanning:
+ m_platformCursor = loadCursorByName("panSouthWestCursor", 7, 7);
+ break;
+ case Cursor::WestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::NorthSouthResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::EastWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::WestPanning:
+ m_platformCursor = loadCursorByName("panWestCursor", 7, 7);
+ break;
+ case Cursor::NorthEastSouthWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENESW);
+ break;
+ case Cursor::NorthWestSouthEastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENWSE);
+ break;
+ case Cursor::ColumnResize:
+ // FIXME: Windows does not have a standard column resize cursor <rdar://problem/5018591>
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::RowResize:
+ // FIXME: Windows does not have a standard row resize cursor <rdar://problem/5018591>
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::VerticalText:
+ m_platformCursor = loadCursorByName("verticalTextCursor", 7, 7);
+ break;
+ case Cursor::Progress:
+ m_platformCursor = loadSharedCursor(0, IDC_APPSTARTING);
+ break;
+ case Cursor::NoDrop:
+ case Cursor::NotAllowed:
+ m_platformCursor = loadSharedCursor(0, IDC_NO);
+ break;
+ case Cursor::ZoomIn:
+ m_platformCursor = loadCursorByName("zoomInCursor", 7, 7);
+ break;
+ case Cursor::ZoomOut:
+ m_platformCursor = loadCursorByName("zoomOutCursor", 7, 7);
+ break;
+ case Cursor::Custom:
+ m_platformCursor = createSharedCursor(m_image.get(), m_hotSpot);
+ if (!m_platformCursor)
+ m_platformCursor = loadSharedCursor(0, IDC_ARROW);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ m_platformCursor = loadSharedCursor(0, IDC_ARROW);
+ break;
+ }
+}
+
+SharedCursor::~SharedCursor()
+{
+ DestroyIcon(m_nativeCursor);
+}
+
+Cursor::Cursor(const Cursor& other)
+ : m_type(other.m_type)
+ , m_image(other.m_image)
+ , m_hotSpot(other.m_hotSpot)
+#if ENABLE(MOUSE_CURSOR_SCALE)
+ , m_imageScaleFactor(other.m_imageScaleFactor)
+#endif
+ , m_platformCursor(other.m_platformCursor)
+{
+}
+
+Cursor& Cursor::operator=(const Cursor& other)
+{
+ m_type = other.m_type;
+ m_image = other.m_image;
+ m_hotSpot = other.m_hotSpot;
+#if ENABLE(MOUSE_CURSOR_SCALE)
+ m_imageScaleFactor = other.m_imageScaleFactor;
+#endif
+ m_platformCursor = other.m_platformCursor;
+ return *this;
+}
+
+Cursor::~Cursor()
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/DefWndProcWindowClass.cpp b/Source/WebCore/platform/win/DefWndProcWindowClass.cpp
new file mode 100644
index 000000000..b07a6dee3
--- /dev/null
+++ b/Source/WebCore/platform/win/DefWndProcWindowClass.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "DefWndProcWindowClass.h"
+
+#include "WebCoreInstanceHandle.h"
+#include <windows.h>
+
+namespace WebCore {
+
+static const wchar_t className[] = L"DefWndProcWindowClass";
+
+static ATOM registerClass()
+{
+ WNDCLASSW wndClass = {0};
+ wndClass.lpszClassName = className;
+ wndClass.lpfnWndProc = ::DefWindowProcW;
+ wndClass.hInstance = instanceHandle();
+
+ return ::RegisterClassW(&wndClass);
+}
+
+const wchar_t* defWndProcWindowClassName()
+{
+ static ATOM atom = registerClass();
+ return className;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/DefWndProcWindowClass.h b/Source/WebCore/platform/win/DefWndProcWindowClass.h
new file mode 100644
index 000000000..346a332ec
--- /dev/null
+++ b/Source/WebCore/platform/win/DefWndProcWindowClass.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 DefWndProcWindowClass_h
+#define DefWndProcWindowClass_h
+
+namespace WebCore {
+
+// Returns the name of a window class that can be used to create a "dummy" window. The window just
+// passes all messages to ::DefWindowProcW. This is useful in situations where you need an HWND but
+// don't need it to have any special behavior.
+const wchar_t* defWndProcWindowClassName();
+
+} // namespace WebCore
+
+#endif // DefWndProcWindowClass_h
diff --git a/Source/WebCore/platform/win/DelayLoadedModulesEnumerator.cpp b/Source/WebCore/platform/win/DelayLoadedModulesEnumerator.cpp
new file mode 100644
index 000000000..aa6df11be
--- /dev/null
+++ b/Source/WebCore/platform/win/DelayLoadedModulesEnumerator.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "DelayLoadedModulesEnumerator.h"
+
+#include "ImportedFunctionsEnumerator.h"
+#include <delayimp.h>
+
+// See <http://msdn.microsoft.com/en-us/magazine/cc301808.aspx> and
+// <http://msdn.microsoft.com/en-us/windows/hardware/gg463119> for more information about the PE
+// image format.
+
+namespace WebCore {
+
+DelayLoadedModulesEnumerator::DelayLoadedModulesEnumerator(const PEImage& image)
+ : m_image(image)
+{
+ if (m_image.isValid())
+ m_descriptor = static_cast<const ImgDelayDescr*>(m_image.dataDirectoryEntryAddress(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT));
+ else
+ m_descriptor = 0;
+}
+
+bool DelayLoadedModulesEnumerator::isAtEnd() const
+{
+ return !m_descriptor || !m_descriptor->rvaHmod;
+}
+
+void DelayLoadedModulesEnumerator::next()
+{
+ ASSERT(!isAtEnd());
+ ++m_descriptor;
+}
+
+const char* DelayLoadedModulesEnumerator::currentModuleName() const
+{
+ ASSERT(!isAtEnd());
+ return static_cast<const char*>(convertPotentialRVAToAddress(m_descriptor->rvaDLLName));
+}
+
+ImportedFunctionsEnumerator DelayLoadedModulesEnumerator::functionsEnumerator() const
+{
+ ASSERT(!isAtEnd());
+
+ const IMAGE_THUNK_DATA* importNameTable = static_cast<const IMAGE_THUNK_DATA*>(convertPotentialRVAToAddress(m_descriptor->rvaINT));
+ const IMAGE_THUNK_DATA* importAddressTable = static_cast<const IMAGE_THUNK_DATA*>(convertPotentialRVAToAddress(m_descriptor->rvaIAT));
+
+ return ImportedFunctionsEnumerator(m_image, importNameTable, importAddressTable);
+}
+
+const void* DelayLoadedModulesEnumerator::convertPotentialRVAToAddress(DWORD potentialRVA) const
+{
+ ASSERT(!isAtEnd());
+
+ if (!(m_descriptor->grAttrs & dlattrRva)) {
+ // m_image is a pre-VC7.0 image, so addresses stored in the ImageDelayDescr are non-relative.
+ return reinterpret_cast<void*>(potentialRVA);
+ }
+
+ return m_image.convertRVAToAddress(potentialRVA);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/DelayLoadedModulesEnumerator.h b/Source/WebCore/platform/win/DelayLoadedModulesEnumerator.h
new file mode 100644
index 000000000..477806c6f
--- /dev/null
+++ b/Source/WebCore/platform/win/DelayLoadedModulesEnumerator.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 DelayLoadedModulesEnumerator_h
+#define DelayLoadedModulesEnumerator_h
+
+#include "ImportedModulesEnumeratorBase.h"
+#include "PEImage.h"
+
+struct ImgDelayDescr;
+
+namespace WebCore {
+
+// Enumerates all delay-loaded modules imported by the given PEImage.
+class DelayLoadedModulesEnumerator : public ImportedModulesEnumeratorBase {
+public:
+ explicit DelayLoadedModulesEnumerator(const PEImage&);
+
+ virtual bool isAtEnd() const;
+ virtual void next();
+
+ virtual const char* currentModuleName() const;
+ virtual ImportedFunctionsEnumerator functionsEnumerator() const;
+
+private:
+ const void* convertPotentialRVAToAddress(DWORD) const;
+
+ PEImage m_image;
+ const ImgDelayDescr* m_descriptor;
+};
+
+} // namespace WebCore
+
+#endif // DelayLoadedModulesEnumerator_h
diff --git a/Source/WebCore/platform/win/DragDataWin.cpp b/Source/WebCore/platform/win/DragDataWin.cpp
new file mode 100644
index 000000000..700570ad5
--- /dev/null
+++ b/Source/WebCore/platform/win/DragDataWin.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Baidu 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 "DragData.h"
+
+#include "COMPtr.h"
+#include "ClipboardUtilitiesWin.h"
+#include "TextEncoding.h"
+#include <objidl.h>
+#include <shlwapi.h>
+#include <wininet.h>
+#include <wtf/Forward.h>
+#include <wtf/Hashmap.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, const IntPoint& globalPosition,
+ DragOperation sourceOperationMask, DragApplicationFlags flags)
+ : m_clientPosition(clientPosition)
+ , m_globalPosition(globalPosition)
+ , m_platformDragData(0)
+ , m_draggingSourceOperationMask(sourceOperationMask)
+ , m_applicationFlags(flags)
+ , m_dragDataMap(data)
+{
+}
+
+bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const
+{
+ if (m_platformDragData)
+ return SUCCEEDED(m_platformDragData->QueryGetData(urlWFormat()))
+ || SUCCEEDED(m_platformDragData->QueryGetData(urlFormat()))
+ || (filenamePolicy == ConvertFilenames
+ && (SUCCEEDED(m_platformDragData->QueryGetData(filenameWFormat()))
+ || SUCCEEDED(m_platformDragData->QueryGetData(filenameFormat()))));
+ return m_dragDataMap.contains(urlWFormat()->cfFormat) || m_dragDataMap.contains(urlFormat()->cfFormat)
+ || (filenamePolicy == ConvertFilenames && (m_dragDataMap.contains(filenameWFormat()->cfFormat) || m_dragDataMap.contains(filenameFormat()->cfFormat)));
+}
+
+const DragDataMap& DragData::dragDataMap()
+{
+ if (!m_dragDataMap.isEmpty() || !m_platformDragData)
+ return m_dragDataMap;
+ // Enumerate clipboard content and load it in the map.
+ COMPtr<IEnumFORMATETC> itr;
+
+ if (FAILED(m_platformDragData->EnumFormatEtc(DATADIR_GET, &itr)) || !itr)
+ return m_dragDataMap;
+
+ FORMATETC dataFormat;
+ while (itr->Next(1, &dataFormat, 0) == S_OK) {
+ Vector<String> dataStrings;
+ getClipboardData(m_platformDragData, &dataFormat, dataStrings);
+ if (!dataStrings.isEmpty())
+ m_dragDataMap.set(dataFormat.cfFormat, dataStrings);
+ }
+ return m_dragDataMap;
+}
+
+void DragData::getDragFileDescriptorData(int& size, String& pathname)
+{
+ size = 0;
+ if (m_platformDragData)
+ getFileDescriptorData(m_platformDragData, size, pathname);
+}
+
+void DragData::getDragFileContentData(int size, void* dataBlob)
+{
+ if (m_platformDragData)
+ getFileContentData(m_platformDragData, size, dataBlob);
+}
+
+String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const
+{
+ return (m_platformDragData) ? getURL(m_platformDragData, filenamePolicy, title) : getURL(&m_dragDataMap, filenamePolicy, title);
+}
+
+bool DragData::containsFiles() const
+{
+#if USE(CF)
+ return (m_platformDragData) ? SUCCEEDED(m_platformDragData->QueryGetData(cfHDropFormat())) : m_dragDataMap.contains(cfHDropFormat()->cfFormat);
+#else
+ return false;
+#endif
+}
+
+unsigned DragData::numberOfFiles() const
+{
+#if USE(CF)
+ if (!m_platformDragData)
+ return 0;
+
+ STGMEDIUM medium;
+ if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium)))
+ return 0;
+
+ HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal));
+
+ if (!hdrop)
+ return 0;
+
+ unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
+
+ DragFinish(hdrop);
+ GlobalUnlock(medium.hGlobal);
+
+ return numFiles;
+#else
+ return 0;
+#endif
+}
+
+void DragData::asFilenames(Vector<String>& result) const
+{
+#if USE(CF)
+ if (m_platformDragData) {
+ WCHAR filename[MAX_PATH];
+
+ STGMEDIUM medium;
+ if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium)))
+ return;
+
+ HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
+
+ if (!hdrop)
+ return;
+
+ const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
+ for (unsigned i = 0; i < numFiles; i++) {
+ if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
+ continue;
+ result.append(static_cast<UChar*>(filename));
+ }
+
+ // Free up memory from drag
+ DragFinish(hdrop);
+
+ GlobalUnlock(medium.hGlobal);
+ return;
+ }
+ result = m_dragDataMap.get(cfHDropFormat()->cfFormat);
+#endif
+}
+
+bool DragData::containsPlainText() const
+{
+ if (m_platformDragData)
+ return SUCCEEDED(m_platformDragData->QueryGetData(plainTextWFormat()))
+ || SUCCEEDED(m_platformDragData->QueryGetData(plainTextFormat()));
+ return m_dragDataMap.contains(plainTextWFormat()->cfFormat) || m_dragDataMap.contains(plainTextFormat()->cfFormat);
+}
+
+String DragData::asPlainText() const
+{
+ return (m_platformDragData) ? getPlainText(m_platformDragData) : getPlainText(&m_dragDataMap);
+}
+
+bool DragData::containsColor() const
+{
+ return false;
+}
+
+bool DragData::canSmartReplace() const
+{
+ if (m_platformDragData)
+ return SUCCEEDED(m_platformDragData->QueryGetData(smartPasteFormat()));
+ return m_dragDataMap.contains(smartPasteFormat()->cfFormat);
+}
+
+bool DragData::containsCompatibleContent() const
+{
+ return containsPlainText() || containsURL()
+ || ((m_platformDragData) ? (containsHTML(m_platformDragData) || containsFilenames(m_platformDragData))
+ : (containsHTML(&m_dragDataMap) || containsFilenames(&m_dragDataMap)))
+ || containsColor();
+}
+
+Color DragData::asColor() const
+{
+ return Color();
+}
+
+}
diff --git a/Source/WebCore/platform/win/DragImageCGWin.cpp b/Source/WebCore/platform/win/DragImageCGWin.cpp
new file mode 100644
index 000000000..ad2598968
--- /dev/null
+++ b/Source/WebCore/platform/win/DragImageCGWin.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2007, 2008, 2013 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 "DragImage.h"
+
+#include "BitmapInfo.h"
+#include "CachedImage.h"
+#include "GraphicsContextCG.h"
+#include "HWndDC.h"
+#include "Image.h"
+
+#include <CoreGraphics/CoreGraphics.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/win/GDIObject.h>
+
+#include <windows.h>
+
+namespace WebCore {
+
+void deallocContext(CGContextRef target)
+{
+ CGContextRelease(target);
+}
+
+GDIObject<HBITMAP> allocImage(HDC dc, IntSize size, CGContextRef *targetRef)
+{
+ BitmapInfo bmpInfo = BitmapInfo::create(size);
+
+ LPVOID bits = nullptr;
+ auto hbmp = adoptGDIObject(::CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0));
+
+ if (!targetRef || !hbmp)
+ return hbmp;
+
+ CGContextRef bitmapContext = CGBitmapContextCreate(bits, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, 8,
+ bmpInfo.bmiHeader.biWidth * 4, deviceRGBColorSpaceRef(),
+ kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
+ if (!bitmapContext)
+ return GDIObject<HBITMAP>();
+
+ *targetRef = bitmapContext;
+ return hbmp;
+}
+
+static CGContextRef createCgContextFromBitmap(HBITMAP bitmap)
+{
+ BITMAP info;
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
+ info.bmWidthBytes, deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
+ return bitmapContext;
+}
+
+DragImageRef scaleDragImage(DragImageRef imageRef, FloatSize scale)
+{
+ // FIXME: due to the way drag images are done on windows we need
+ // to preprocess the alpha channel <rdar://problem/5015946>
+ if (!imageRef)
+ return 0;
+
+ GDIObject<HBITMAP> hbmp;
+ auto image = adoptGDIObject(imageRef);
+
+ IntSize srcSize = dragImageSize(image.get());
+ IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height()));
+
+ HWndDC dc(0);
+ auto dstDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ if (!dstDC)
+ goto exit;
+
+ CGContextRef targetContext;
+ hbmp = allocImage(dstDC.get(), dstSize, &targetContext);
+ if (!hbmp)
+ goto exit;
+
+ CGContextRef srcContext = createCgContextFromBitmap(image.get());
+ CGImageRef srcImage = CGBitmapContextCreateImage(srcContext);
+ CGRect rect;
+ rect.origin.x = 0;
+ rect.origin.y = 0;
+ rect.size = dstSize;
+ CGContextDrawImage(targetContext, rect, srcImage);
+ CGImageRelease(srcImage);
+ CGContextRelease(srcContext);
+ CGContextRelease(targetContext);
+
+exit:
+ if (!hbmp)
+ hbmp.swap(image);
+ return hbmp.leak();
+}
+
+DragImageRef createDragImageFromImage(Image* img, ImageOrientationDescription)
+{
+ HWndDC dc(0);
+ auto workingDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ if (!workingDC)
+ return 0;
+
+ CGContextRef drawContext = 0;
+ auto hbmp = allocImage(workingDC.get(), IntSize(img->size()), &drawContext);
+ if (!hbmp || !drawContext)
+ return 0;
+
+ CGImageRef srcImage = img->getCGImageRef();
+ CGRect rect;
+ rect.size = IntSize(img->size());
+ rect.origin.x = 0;
+ rect.origin.y = -rect.size.height;
+ static const CGFloat white [] = {1.0, 1.0, 1.0, 1.0};
+ CGContextScaleCTM(drawContext, 1, -1);
+ CGContextSetFillColor(drawContext, white);
+ CGContextFillRect(drawContext, rect);
+ if (srcImage) {
+ CGContextSetBlendMode(drawContext, kCGBlendModeNormal);
+ CGContextDrawImage(drawContext, rect, srcImage);
+ }
+ CGContextRelease(drawContext);
+
+ return hbmp.leak();
+}
+
+}
diff --git a/Source/WebCore/platform/win/DragImageCairoWin.cpp b/Source/WebCore/platform/win/DragImageCairoWin.cpp
new file mode 100644
index 000000000..731376968
--- /dev/null
+++ b/Source/WebCore/platform/win/DragImageCairoWin.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2008, 2013 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 "DragImage.h"
+
+#include "BitmapInfo.h"
+#include "CachedImage.h"
+#include "GraphicsContext.h"
+#include "GraphicsContextPlatformPrivateCairo.h"
+#include "HWndDC.h"
+#include "Image.h"
+#include <cairo-win32.h>
+#include <windows.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/win/GDIObject.h>
+
+namespace WebCore {
+
+void deallocContext(PlatformContextCairo* target)
+{
+ delete target;
+}
+
+GDIObject<HBITMAP> allocImage(HDC dc, IntSize size, PlatformContextCairo** targetRef)
+{
+ BitmapInfo bmpInfo = BitmapInfo::create(size);
+
+ LPVOID bits;
+ auto hbmp = adoptGDIObject(::CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0));
+
+ // At this point, we have a Cairo surface that points to a Windows DIB. The DIB interprets
+ // with the opposite meaning of positive Y axis, so everything we draw into this cairo
+ // context is going to be upside down.
+ if (!targetRef)
+ return hbmp;
+
+ cairo_surface_t* bitmapContext = cairo_image_surface_create_for_data((unsigned char*)bits,
+ CAIRO_FORMAT_ARGB32,
+ bmpInfo.bmiHeader.biWidth,
+ bmpInfo.bmiHeader.biHeight,
+ bmpInfo.bmiHeader.biWidth * 4);
+
+ if (!bitmapContext)
+ return GDIObject<HBITMAP>();
+
+ cairo_t* cr = cairo_create(bitmapContext);
+ cairo_surface_destroy(bitmapContext);
+
+ // At this point, we have a Cairo surface that points to a Windows DIB. The DIB interprets
+ // with the opposite meaning of positive Y axis, so everything we draw into this cairo
+ // context is going to be upside down.
+ //
+ // So, we must invert the CTM for the context so that drawing commands will be flipped
+ // before they get written to the internal buffer.
+ cairo_matrix_t matrix;
+ cairo_matrix_init(&matrix, 1.0, 0.0, 0.0, -1.0, 0.0, size.height());
+ cairo_set_matrix(cr, &matrix);
+
+ *targetRef = new PlatformGraphicsContext(cr);
+ cairo_destroy(cr);
+
+ return hbmp;
+}
+
+static cairo_surface_t* createCairoContextFromBitmap(HBITMAP bitmap)
+{
+ BITMAP info;
+ GetObject(bitmap, sizeof(info), &info);
+ ASSERT(info.bmBitsPixel == 32);
+
+ // At this point, we have a Cairo surface that points to a Windows BITMAP. The BITMAP
+ // has the opposite meaning of positive Y axis, so everything we draw into this cairo
+ // context is going to be upside down.
+ return cairo_image_surface_create_for_data((unsigned char*)info.bmBits,
+ CAIRO_FORMAT_ARGB32,
+ info.bmWidth,
+ info.bmHeight,
+ info.bmWidthBytes);
+}
+
+DragImageRef scaleDragImage(DragImageRef imageRef, FloatSize scale)
+{
+ // FIXME: due to the way drag images are done on windows we need
+ // to preprocess the alpha channel <rdar://problem/5015946>
+ if (!imageRef)
+ return 0;
+
+ GDIObject<HBITMAP> hbmp;
+ auto image = adoptGDIObject(imageRef);
+
+ IntSize srcSize = dragImageSize(image.get());
+ IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height()));
+
+ HWndDC dc(0);
+ auto dstDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ if (!dstDC)
+ goto exit;
+
+ PlatformContextCairo* targetContext;
+ hbmp = allocImage(dstDC.get(), dstSize, &targetContext);
+ if (!hbmp)
+ goto exit;
+
+ cairo_surface_t* srcImage = createCairoContextFromBitmap(image.get());
+
+ // Scale the target surface to the new image size, and flip it
+ // so that when we set the srcImage as the surface it will draw
+ // right-side-up.
+ cairo_t* cr = targetContext->cr();
+ cairo_translate(cr, 0, dstSize.height());
+ cairo_scale(cr, scale.width(), -scale.height());
+ cairo_set_source_surface(cr, srcImage, 0.0, 0.0);
+
+ // Now we can paint and get the correct result
+ cairo_paint(cr);
+
+ cairo_surface_destroy(srcImage);
+ deallocContext(targetContext);
+
+exit:
+ if (!hbmp)
+ hbmp.swap(image);
+ return hbmp.leak();
+}
+
+DragImageRef createDragImageFromImage(Image* img, ImageOrientationDescription)
+{
+ HWndDC dc(0);
+ auto workingDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ if (!workingDC)
+ return 0;
+
+ PlatformContextCairo* drawContext = 0;
+ auto hbmp = allocImage(workingDC.get(), IntSize(img->size()), &drawContext);
+ if (!hbmp || !drawContext)
+ return 0;
+
+ cairo_t* cr = drawContext->cr();
+ cairo_set_source_rgb(cr, 1.0, 0.0, 1.0);
+ cairo_fill_preserve(cr);
+
+ RefPtr<cairo_surface_t> surface = img->nativeImageForCurrentFrame();
+ if (surface) {
+ // Draw the image.
+ cairo_set_source_surface(cr, surface.get(), 0.0, 0.0);
+ cairo_paint(cr);
+ }
+
+ deallocContext(drawContext);
+
+ return hbmp.leak();
+}
+
+}
diff --git a/Source/WebCore/platform/win/DragImageWin.cpp b/Source/WebCore/platform/win/DragImageWin.cpp
new file mode 100644
index 000000000..989a0b546
--- /dev/null
+++ b/Source/WebCore/platform/win/DragImageWin.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2007, 2008, 2013 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 "DragImage.h"
+
+#include "FloatRoundedRect.h"
+#include "FontCascade.h"
+#include "FontDescription.h"
+#include "FontSelector.h"
+#include "GraphicsContext.h"
+#include "HWndDC.h"
+#include "Image.h"
+#include "URL.h"
+#include "StringTruncator.h"
+#include "TextRun.h"
+#include "WebCoreTextRenderer.h"
+#include <wtf/RetainPtr.h>
+#include <wtf/win/GDIObject.h>
+
+#include <windows.h>
+
+namespace WebCore {
+
+GDIObject<HBITMAP> allocImage(HDC, IntSize, PlatformGraphicsContext** targetRef);
+void deallocContext(PlatformGraphicsContext* target);
+
+IntSize dragImageSize(DragImageRef image)
+{
+ if (!image)
+ return IntSize();
+ BITMAP b;
+ GetObject(image, sizeof(BITMAP), &b);
+ return IntSize(b.bmWidth, b.bmHeight);
+}
+
+void deleteDragImage(DragImageRef image)
+{
+ if (image)
+ ::DeleteObject(image);
+}
+
+DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
+{
+ //We don't do this on windows as the dragimage is blended by the OS
+ return image;
+}
+
+DragImageRef createDragImageIconForCachedImageFilename(const String& filename)
+{
+ SHFILEINFO shfi = {0};
+ String fname = filename;
+ if (FAILED(SHGetFileInfo(static_cast<LPCWSTR>(fname.charactersWithNullTermination().data()), FILE_ATTRIBUTE_NORMAL,
+ &shfi, sizeof(shfi), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES)))
+ return 0;
+
+ ICONINFO iconInfo;
+ if (!GetIconInfo(shfi.hIcon, &iconInfo)) {
+ DestroyIcon(shfi.hIcon);
+ return 0;
+ }
+
+ DestroyIcon(shfi.hIcon);
+ DeleteObject(iconInfo.hbmMask);
+
+ return iconInfo.hbmColor;
+}
+
+const float DragLabelBorderX = 4;
+// Keep border_y in synch with DragController::LinkDragBorderInset.
+const float DragLabelBorderY = 2;
+const float DragLabelRadius = 5;
+const float LabelBorderYOffset = 2;
+
+const float MinDragLabelWidthBeforeClip = 120;
+const float MaxDragLabelWidth = 200;
+const float MaxDragLabelStringWidth = (MaxDragLabelWidth - 2 * DragLabelBorderX);
+
+const float DragLinkLabelFontsize = 11;
+const float DragLinkUrlFontSize = 10;
+
+static FontCascade dragLabelFont(int size, bool bold, FontRenderingMode renderingMode)
+{
+ FontCascade result;
+ NONCLIENTMETRICS metrics;
+ metrics.cbSize = sizeof(metrics);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);
+
+ FontCascadeDescription description;
+ description.setWeight(bold ? FontWeightBold : FontWeightNormal);
+ description.setOneFamily(metrics.lfSmCaptionFont.lfFaceName);
+ description.setSpecifiedSize((float)size);
+ description.setComputedSize((float)size);
+ description.setRenderingMode(renderingMode);
+ result = FontCascade(description, 0, 0);
+ result.update(0);
+ return result;
+}
+
+DragImageRef createDragImageForLink(URL& url, const String& inLabel, FontRenderingMode fontRenderingMode)
+{
+ // This is more or less an exact match for the Mac OS X code.
+
+ const FontCascade* labelFont;
+ const FontCascade* urlFont;
+
+ if (fontRenderingMode == FontRenderingMode::Alternate) {
+ static const FontCascade alternateRenderingModeLabelFont = dragLabelFont(DragLinkLabelFontsize, true, FontRenderingMode::Alternate);
+ static const FontCascade alternateRenderingModeURLFont = dragLabelFont(DragLinkUrlFontSize, false, FontRenderingMode::Alternate);
+ labelFont = &alternateRenderingModeLabelFont;
+ urlFont = &alternateRenderingModeURLFont;
+ } else {
+ static const FontCascade normalRenderingModeLabelFont = dragLabelFont(DragLinkLabelFontsize, true, FontRenderingMode::Normal);
+ static const FontCascade normalRenderingModeURLFont = dragLabelFont(DragLinkUrlFontSize, false, FontRenderingMode::Normal);
+ labelFont = &normalRenderingModeLabelFont;
+ urlFont = &normalRenderingModeURLFont;
+ }
+
+ bool drawURLString = true;
+ bool clipURLString = false;
+ bool clipLabelString = false;
+
+ String urlString = url.string();
+ String label = inLabel;
+ if (label.isEmpty()) {
+ drawURLString = false;
+ label = urlString;
+ }
+
+ // First step in drawing the link drag image width.
+ TextRun labelRun(label);
+ TextRun urlRun(urlString);
+ IntSize labelSize(labelFont->width(labelRun), labelFont->fontMetrics().ascent() + labelFont->fontMetrics().descent());
+
+ if (labelSize.width() > MaxDragLabelStringWidth) {
+ labelSize.setWidth(MaxDragLabelStringWidth);
+ clipLabelString = true;
+ }
+
+ IntSize urlStringSize;
+ IntSize imageSize(labelSize.width() + DragLabelBorderX * 2, labelSize.height() + DragLabelBorderY * 2);
+
+ if (drawURLString) {
+ urlStringSize.setWidth(urlFont->width(urlRun));
+ urlStringSize.setHeight(urlFont->fontMetrics().ascent() + urlFont->fontMetrics().descent());
+ imageSize.setHeight(imageSize.height() + urlStringSize.height());
+ if (urlStringSize.width() > MaxDragLabelStringWidth) {
+ imageSize.setWidth(MaxDragLabelWidth);
+ clipURLString = true;
+ } else
+ imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()) + DragLabelBorderX * 2);
+ }
+
+ // We now know how big the image needs to be, so we create and
+ // fill the background
+ HWndDC dc(0);
+ auto workingDC = adoptGDIObject(::CreateCompatibleDC(dc));
+ if (!workingDC)
+ return 0;
+
+ PlatformGraphicsContext* contextRef;
+ auto image = allocImage(workingDC.get(), imageSize, &contextRef);
+ if (!image)
+ return 0;
+
+ ::SelectObject(workingDC.get(), image.get());
+ GraphicsContext context(contextRef);
+ // On Mac alpha is {0.7, 0.7, 0.7, 0.8}, however we can't control alpha
+ // for drag images on win, so we use 1
+ static const Color backgroundColor(140, 140, 140);
+ static const IntSize radii(DragLabelRadius, DragLabelRadius);
+ IntRect rect(0, 0, imageSize.width(), imageSize.height());
+ context.fillRoundedRect(FloatRoundedRect(rect, radii, radii, radii, radii), backgroundColor);
+
+ // Draw the text
+ static const Color topColor(0, 0, 0, 255); // original alpha = 0.75
+ static const Color bottomColor(255, 255, 255, 127); // original alpha = 0.5
+ if (drawURLString) {
+ if (clipURLString)
+ urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DragLabelBorderX * 2.0f), *urlFont);
+ IntPoint textPos(DragLabelBorderX, imageSize.height() - (LabelBorderYOffset + urlFont->fontMetrics().descent()));
+ WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, *urlFont, topColor, bottomColor);
+ }
+
+ if (clipLabelString)
+ label = StringTruncator::rightTruncate(label, imageSize.width() - (DragLabelBorderX * 2.0f), *labelFont);
+
+ IntPoint textPos(DragLabelBorderX, DragLabelBorderY + labelFont->pixelSize());
+ WebCoreDrawDoubledTextAtPoint(context, label, textPos, *labelFont, topColor, bottomColor);
+
+ deallocContext(contextRef);
+ return image.leak();
+}
+
+}
diff --git a/Source/WebCore/platform/win/EventLoopWin.cpp b/Source/WebCore/platform/win/EventLoopWin.cpp
new file mode 100644
index 000000000..ece320f6f
--- /dev/null
+++ b/Source/WebCore/platform/win/EventLoopWin.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 "EventLoop.h"
+
+#include <windows.h>
+
+namespace WebCore {
+
+void EventLoop::cycle()
+{
+ MSG msg;
+ if (!GetMessage(&msg, 0, 0, 0)) {
+ m_ended = true;
+ return;
+ }
+
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/FileSystemWin.cpp b/Source/WebCore/platform/win/FileSystemWin.cpp
new file mode 100644
index 000000000..c2b93e438
--- /dev/null
+++ b/Source/WebCore/platform/win/FileSystemWin.cpp
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "FileSystem.h"
+
+#include "FileMetadata.h"
+#include "NotImplemented.h"
+#include "PathWalker.h"
+#include <wtf/CryptographicallyRandomNumber.h>
+#include <wtf/HashMap.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+
+#include <windows.h>
+#include <shlobj.h>
+#include <shlwapi.h>
+
+namespace WebCore {
+
+static const ULONGLONG kSecondsFromFileTimeToTimet = 11644473600;
+
+static bool getFindData(String path, WIN32_FIND_DATAW& findData)
+{
+ HANDLE handle = FindFirstFileW(path.charactersWithNullTermination().data(), &findData);
+ if (handle == INVALID_HANDLE_VALUE)
+ return false;
+ FindClose(handle);
+ return true;
+}
+
+static bool getFileSizeFromFindData(const WIN32_FIND_DATAW& findData, long long& size)
+{
+ ULARGE_INTEGER fileSize;
+ fileSize.HighPart = findData.nFileSizeHigh;
+ fileSize.LowPart = findData.nFileSizeLow;
+
+ if (fileSize.QuadPart > static_cast<ULONGLONG>(std::numeric_limits<long long>::max()))
+ return false;
+
+ size = fileSize.QuadPart;
+ return true;
+}
+
+static bool getFileSizeFromByHandleFileInformationStructure(const BY_HANDLE_FILE_INFORMATION& fileInformation, long long& size)
+{
+ ULARGE_INTEGER fileSize;
+ fileSize.HighPart = fileInformation.nFileSizeHigh;
+ fileSize.LowPart = fileInformation.nFileSizeLow;
+
+ if (fileSize.QuadPart > static_cast<ULONGLONG>(std::numeric_limits<long long>::max()))
+ return false;
+
+ size = fileSize.QuadPart;
+ return true;
+}
+
+static void getFileCreationTimeFromFindData(const WIN32_FIND_DATAW& findData, time_t& time)
+{
+ ULARGE_INTEGER fileTime;
+ fileTime.HighPart = findData.ftCreationTime.dwHighDateTime;
+ fileTime.LowPart = findData.ftCreationTime.dwLowDateTime;
+
+ // Information about converting time_t to FileTime is available at http://msdn.microsoft.com/en-us/library/ms724228%28v=vs.85%29.aspx
+ time = fileTime.QuadPart / 10000000 - kSecondsFromFileTimeToTimet;
+}
+
+
+static void getFileModificationTimeFromFindData(const WIN32_FIND_DATAW& findData, time_t& time)
+{
+ ULARGE_INTEGER fileTime;
+ fileTime.HighPart = findData.ftLastWriteTime.dwHighDateTime;
+ fileTime.LowPart = findData.ftLastWriteTime.dwLowDateTime;
+
+ // Information about converting time_t to FileTime is available at http://msdn.microsoft.com/en-us/library/ms724228%28v=vs.85%29.aspx
+ time = fileTime.QuadPart / 10000000 - kSecondsFromFileTimeToTimet;
+}
+
+bool getFileSize(const String& path, long long& size)
+{
+ WIN32_FIND_DATAW findData;
+ if (!getFindData(path, findData))
+ return false;
+
+ return getFileSizeFromFindData(findData, size);
+}
+
+bool getFileSize(PlatformFileHandle fileHandle, long long& size)
+{
+ BY_HANDLE_FILE_INFORMATION fileInformation;
+ if (!::GetFileInformationByHandle(fileHandle, &fileInformation))
+ return false;
+
+ return getFileSizeFromByHandleFileInformationStructure(fileInformation, size);
+}
+
+bool getFileModificationTime(const String& path, time_t& time)
+{
+ WIN32_FIND_DATAW findData;
+ if (!getFindData(path, findData))
+ return false;
+
+ getFileModificationTimeFromFindData(findData, time);
+ return true;
+}
+
+bool getFileCreationTime(const String& path, time_t& time)
+{
+ WIN32_FIND_DATAW findData;
+ if (!getFindData(path, findData))
+ return false;
+
+ getFileCreationTimeFromFindData(findData, time);
+ return true;
+}
+
+bool getFileMetadata(const String& path, FileMetadata& metadata)
+{
+ WIN32_FIND_DATAW findData;
+ if (!getFindData(path, findData))
+ return false;
+
+ if (!getFileSizeFromFindData(findData, metadata.length))
+ return false;
+
+ time_t modificationTime;
+ getFileModificationTimeFromFindData(findData, modificationTime);
+ metadata.modificationTime = modificationTime;
+
+ metadata.type = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FileMetadata::TypeDirectory : FileMetadata::TypeFile;
+
+ return true;
+}
+
+bool fileExists(const String& path)
+{
+ WIN32_FIND_DATAW findData;
+ return getFindData(path, findData);
+}
+
+bool deleteFile(const String& path)
+{
+ String filename = path;
+ return !!DeleteFileW(filename.charactersWithNullTermination().data());
+}
+
+bool deleteEmptyDirectory(const String& path)
+{
+ String filename = path;
+ return !!RemoveDirectoryW(filename.charactersWithNullTermination().data());
+}
+
+String pathByAppendingComponent(const String& path, const String& component)
+{
+ Vector<UChar> buffer(MAX_PATH);
+
+ if (path.length() + 1 > buffer.size())
+ return String();
+
+ StringView(path).getCharactersWithUpconvert(buffer.data());
+ buffer[path.length()] = '\0';
+
+ if (!PathAppendW(buffer.data(), component.charactersWithNullTermination().data()))
+ return String();
+
+ buffer.shrink(wcslen(buffer.data()));
+
+ return String::adopt(buffer);
+}
+
+#if !USE(CF)
+
+CString fileSystemRepresentation(const String& path)
+{
+ auto upconvertedCharacters = path.upconvertedCharacters();
+
+ const UChar* characters = upconvertedCharacters;
+ int size = WideCharToMultiByte(CP_ACP, 0, characters, path.length(), 0, 0, 0, 0) - 1;
+
+ char* buffer;
+ CString string = CString::newUninitialized(size, buffer);
+
+ WideCharToMultiByte(CP_ACP, 0, characters, path.length(), buffer, size, 0, 0);
+
+ return string;
+}
+
+#endif // !USE(CF)
+
+bool makeAllDirectories(const String& path)
+{
+ String fullPath = path;
+ if (SHCreateDirectoryEx(0, fullPath.charactersWithNullTermination().data(), 0) != ERROR_SUCCESS) {
+ DWORD error = GetLastError();
+ if (error != ERROR_FILE_EXISTS && error != ERROR_ALREADY_EXISTS) {
+ LOG_ERROR("Failed to create path %s", path.ascii().data());
+ return false;
+ }
+ }
+ return true;
+}
+
+String homeDirectoryPath()
+{
+ notImplemented();
+ return "";
+}
+
+String pathGetFileName(const String& path)
+{
+ return String(::PathFindFileName(String(path).charactersWithNullTermination().data()));
+}
+
+String directoryName(const String& path)
+{
+ String name = path.left(path.length() - pathGetFileName(path).length());
+ if (name.characterStartingAt(name.length() - 1) == '\\') {
+ // Remove any trailing "\".
+ name.truncate(name.length() - 1);
+ }
+ return name;
+}
+
+static String bundleName()
+{
+ DEPRECATED_DEFINE_STATIC_LOCAL(String, name, (ASCIILiteral("WebKit")));
+
+#if USE(CF)
+ static bool initialized;
+
+ if (!initialized) {
+ initialized = true;
+
+ if (CFBundleRef bundle = CFBundleGetMainBundle())
+ if (CFTypeRef bundleExecutable = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleExecutableKey))
+ if (CFGetTypeID(bundleExecutable) == CFStringGetTypeID())
+ name = reinterpret_cast<CFStringRef>(bundleExecutable);
+ }
+#endif
+
+ return name;
+}
+
+static String storageDirectory(DWORD pathIdentifier)
+{
+ Vector<UChar> buffer(MAX_PATH);
+ if (FAILED(SHGetFolderPathW(0, pathIdentifier | CSIDL_FLAG_CREATE, 0, 0, buffer.data())))
+ return String();
+ buffer.resize(wcslen(buffer.data()));
+ String directory = String::adopt(buffer);
+
+ DEPRECATED_DEFINE_STATIC_LOCAL(String, companyNameDirectory, (ASCIILiteral("Apple Computer\\")));
+ directory = pathByAppendingComponent(directory, companyNameDirectory + bundleName());
+ if (!makeAllDirectories(directory))
+ return String();
+
+ return directory;
+}
+
+static String cachedStorageDirectory(DWORD pathIdentifier)
+{
+ static HashMap<DWORD, String> directories;
+
+ HashMap<DWORD, String>::iterator it = directories.find(pathIdentifier);
+ if (it != directories.end())
+ return it->value;
+
+ String directory = storageDirectory(pathIdentifier);
+ directories.add(pathIdentifier, directory);
+
+ return directory;
+}
+
+String openTemporaryFile(const String&, PlatformFileHandle& handle)
+{
+ handle = INVALID_HANDLE_VALUE;
+
+ wchar_t tempPath[MAX_PATH];
+ int tempPathLength = ::GetTempPathW(WTF_ARRAY_LENGTH(tempPath), tempPath);
+ if (tempPathLength <= 0 || tempPathLength > WTF_ARRAY_LENGTH(tempPath))
+ return String();
+
+ String proposedPath;
+ do {
+ wchar_t tempFile[] = L"XXXXXXXX.tmp"; // Use 8.3 style name (more characters aren't helpful due to 8.3 short file names)
+ const int randomPartLength = 8;
+ cryptographicallyRandomValues(tempFile, randomPartLength * sizeof(wchar_t));
+
+ // Limit to valid filesystem characters, also excluding others that could be problematic, like punctuation.
+ // don't include both upper and lowercase since Windows file systems are typically not case sensitive.
+ const char validChars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+ for (int i = 0; i < randomPartLength; ++i)
+ tempFile[i] = validChars[tempFile[i] % (sizeof(validChars) - 1)];
+
+ ASSERT(wcslen(tempFile) == WTF_ARRAY_LENGTH(tempFile) - 1);
+
+ proposedPath = pathByAppendingComponent(tempPath, tempFile);
+ if (proposedPath.isEmpty())
+ break;
+
+ // use CREATE_NEW to avoid overwriting an existing file with the same name
+ handle = ::CreateFileW(proposedPath.charactersWithNullTermination().data(), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
+ } while (!isHandleValid(handle) && GetLastError() == ERROR_ALREADY_EXISTS);
+
+ if (!isHandleValid(handle))
+ return String();
+
+ return proposedPath;
+}
+
+PlatformFileHandle openFile(const String& path, FileOpenMode mode)
+{
+ DWORD desiredAccess = 0;
+ DWORD creationDisposition = 0;
+ switch (mode) {
+ case OpenForRead:
+ desiredAccess = GENERIC_READ;
+ creationDisposition = OPEN_EXISTING;
+ break;
+ case OpenForWrite:
+ desiredAccess = GENERIC_WRITE;
+ creationDisposition = CREATE_ALWAYS;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ String destination = path;
+ return CreateFile(destination.charactersWithNullTermination().data(), desiredAccess, 0, 0, creationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
+}
+
+void closeFile(PlatformFileHandle& handle)
+{
+ if (isHandleValid(handle)) {
+ ::CloseHandle(handle);
+ handle = invalidPlatformFileHandle;
+ }
+}
+
+long long seekFile(PlatformFileHandle handle, long long offset, FileSeekOrigin origin)
+{
+ DWORD moveMethod = FILE_BEGIN;
+
+ if (origin == SeekFromCurrent)
+ moveMethod = FILE_CURRENT;
+ else if (origin == SeekFromEnd)
+ moveMethod = FILE_END;
+
+ LARGE_INTEGER largeOffset;
+ largeOffset.QuadPart = offset;
+
+ largeOffset.LowPart = SetFilePointer(handle, largeOffset.LowPart, &largeOffset.HighPart, moveMethod);
+
+ if (largeOffset.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
+ return -1;
+
+ return largeOffset.QuadPart;
+}
+
+int writeToFile(PlatformFileHandle handle, const char* data, int length)
+{
+ if (!isHandleValid(handle))
+ return -1;
+
+ DWORD bytesWritten;
+ bool success = WriteFile(handle, data, length, &bytesWritten, 0);
+
+ if (!success)
+ return -1;
+ return static_cast<int>(bytesWritten);
+}
+
+int readFromFile(PlatformFileHandle handle, char* data, int length)
+{
+ if (!isHandleValid(handle))
+ return -1;
+
+ DWORD bytesRead;
+ bool success = ::ReadFile(handle, data, length, &bytesRead, 0);
+
+ if (!success)
+ return -1;
+ return static_cast<int>(bytesRead);
+}
+
+bool hardLinkOrCopyFile(const String& source, const String& destination)
+{
+ return !!::CopyFile(source.charactersWithNullTermination().data(), destination.charactersWithNullTermination().data(), TRUE);
+}
+
+bool unloadModule(PlatformModule module)
+{
+ return ::FreeLibrary(module);
+}
+
+String localUserSpecificStorageDirectory()
+{
+ return cachedStorageDirectory(CSIDL_LOCAL_APPDATA);
+}
+
+String roamingUserSpecificStorageDirectory()
+{
+ return cachedStorageDirectory(CSIDL_APPDATA);
+}
+
+Vector<String> listDirectory(const String& directory, const String& filter)
+{
+ Vector<String> entries;
+
+ PathWalker walker(directory, filter);
+ if (!walker.isValid())
+ return entries;
+
+ do {
+ if (walker.data().dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ continue;
+
+ entries.append(directory + "\\" + reinterpret_cast<const UChar*>(walker.data().cFileName));
+ } while (walker.step());
+
+ return entries;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/GDIObjectCounter.cpp b/Source/WebCore/platform/win/GDIObjectCounter.cpp
new file mode 100644
index 000000000..a939f2b52
--- /dev/null
+++ b/Source/WebCore/platform/win/GDIObjectCounter.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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"
+
+#ifndef NDEBUG
+
+#include "GDIObjectCounter.h"
+
+#include "Logging.h"
+#include <wtf/text/CString.h>
+
+#include <windows.h>
+
+namespace WebCore {
+
+GDIObjectCounter::GDIObjectCounter(const String& identifier)
+{
+ init(identifier);
+}
+
+GDIObjectCounter::GDIObjectCounter(const String& className, void* instance)
+{
+ init(String::format("%s (%p)", className.latin1().data(), instance));
+}
+
+void GDIObjectCounter::init(const String& identifier)
+{
+ m_identifier = identifier;
+ m_startCount = currentGDIObjectsInUse();
+ m_endCount = 0;
+}
+
+GDIObjectCounter::~GDIObjectCounter()
+{
+ m_endCount = currentGDIObjectsInUse();
+ int leaked = m_endCount - m_startCount;
+ if (leaked != 0)
+ LOG(PlatformLeaks, "%s: leaked %d GDI object%s!", m_identifier.latin1().data(), leaked, leaked == 1 ? "" : "s");
+}
+
+unsigned GDIObjectCounter::currentGDIObjectsInUse()
+{
+ return ::GetGuiResources(::GetCurrentProcess(), GR_GDIOBJECTS);
+}
+
+} // namespace WebCore
+
+#endif // !defined(NDEBUG)
diff --git a/Source/WebCore/platform/win/GDIObjectCounter.h b/Source/WebCore/platform/win/GDIObjectCounter.h
new file mode 100644
index 000000000..99f46608b
--- /dev/null
+++ b/Source/WebCore/platform/win/GDIObjectCounter.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 GDIObjectCounter_h
+#define GDIObjectCounter_h
+
+#ifdef NDEBUG
+#define LOCAL_GDI_COUNTER(num, identifier) ((void)0)
+#else
+#define LOCAL_GDI_COUNTER(num, identifier) GDIObjectCounter counter##num(identifier)
+#endif
+
+#ifndef NDEBUG
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+ class GDIObjectCounter {
+ public:
+ GDIObjectCounter(const String& identifier);
+ GDIObjectCounter(const String& className, void* instance);
+ ~GDIObjectCounter();
+
+ static unsigned currentGDIObjectsInUse();
+
+ private:
+ void init(const String& identifier);
+ String m_identifier;
+ unsigned m_startCount;
+ unsigned m_endCount;
+ };
+
+} // namespace WebCore
+
+#endif // !defined(NDEBUG)
+
+#endif // !defined(GDIObjectCounter_h)
diff --git a/Source/WebCore/platform/win/GDIUtilities.cpp b/Source/WebCore/platform/win/GDIUtilities.cpp
new file mode 100644
index 000000000..f1606b06e
--- /dev/null
+++ b/Source/WebCore/platform/win/GDIUtilities.cpp
@@ -0,0 +1,39 @@
+/*
+* Copyright (C) 2015 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 "GDIUtilities.h"
+
+#include "HWndDC.h"
+
+namespace WebCore {
+
+float deviceScaleFactorForWindow(HWND window)
+{
+ HWndDC dc(window);
+ return ::GetDeviceCaps(dc, LOGPIXELSX) / 96.0f;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/GDIUtilities.h b/Source/WebCore/platform/win/GDIUtilities.h
new file mode 100644
index 000000000..29b90e8ff
--- /dev/null
+++ b/Source/WebCore/platform/win/GDIUtilities.h
@@ -0,0 +1,37 @@
+/*
+* Copyright (C) 2015 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 GDIUtilties_h
+#define GDIUtilties_h
+
+#include <windows.h>
+
+namespace WebCore {
+
+WEBCORE_EXPORT float deviceScaleFactorForWindow(HWND);
+
+} // namespace WebCore
+
+#endif // GDIUtilties_h
diff --git a/Source/WebCore/platform/win/HWndDC.h b/Source/WebCore/platform/win/HWndDC.h
new file mode 100644
index 000000000..c7586c3e5
--- /dev/null
+++ b/Source/WebCore/platform/win/HWndDC.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 Google 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 HWndDC_h
+#define HWndDC_h
+
+#include <windows.h>
+#include <wtf/NonCopyable.h>
+
+namespace WebCore {
+
+class HWndDC {
+ WTF_MAKE_NONCOPYABLE(HWndDC);
+public:
+ HWndDC()
+ : m_hwnd(0)
+ , m_hdc(0)
+ {
+ }
+
+ explicit HWndDC(HWND hwnd)
+ : m_hwnd(hwnd)
+ , m_hdc(::GetDC(hwnd))
+ {
+ }
+
+ HWndDC(HWND hwnd, HRGN hrgnClip, DWORD flags)
+ : m_hwnd(hwnd)
+ , m_hdc(::GetDCEx(hwnd, hrgnClip, flags))
+ {
+ }
+
+ ~HWndDC()
+ {
+ clear();
+ }
+
+ HDC setHWnd(HWND hwnd)
+ {
+ clear();
+ m_hwnd = hwnd;
+ m_hdc = ::GetDC(hwnd);
+ return m_hdc;
+ }
+
+ void clear()
+ {
+ if (!m_hdc)
+ return;
+ ::ReleaseDC(m_hwnd, m_hdc);
+ m_hwnd = 0;
+ m_hdc = 0;
+ }
+
+ operator HDC()
+ {
+ return m_hdc;
+ }
+
+private:
+ HWND m_hwnd;
+ HDC m_hdc;
+};
+
+} // namespace WebCore
+
+#endif // HWndDC_h
diff --git a/Source/WebCore/platform/win/ImportedFunctionsEnumerator.cpp b/Source/WebCore/platform/win/ImportedFunctionsEnumerator.cpp
new file mode 100644
index 000000000..f1100bbed
--- /dev/null
+++ b/Source/WebCore/platform/win/ImportedFunctionsEnumerator.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "ImportedFunctionsEnumerator.h"
+
+// See <http://msdn.microsoft.com/en-us/magazine/cc301808.aspx> and
+// <http://msdn.microsoft.com/en-us/windows/hardware/gg463119> for more information about the PE
+// image format.
+
+namespace WebCore {
+
+ImportedFunctionsEnumerator::ImportedFunctionsEnumerator(const PEImage& image, const IMAGE_THUNK_DATA* importNameTable, const IMAGE_THUNK_DATA* importAddressTable)
+ : m_image(image)
+ , m_nameTableEntry(importNameTable)
+ , m_addressTableEntry(importAddressTable)
+{
+ ASSERT(!importNameTable == !importAddressTable);
+}
+
+bool ImportedFunctionsEnumerator::isAtEnd() const
+{
+ ASSERT(!m_nameTableEntry || !m_nameTableEntry->u1.AddressOfData == !m_addressTableEntry->u1.Function);
+ return !m_nameTableEntry || !m_nameTableEntry->u1.AddressOfData;
+}
+
+void ImportedFunctionsEnumerator::next()
+{
+ ASSERT(!isAtEnd());
+ ++m_nameTableEntry;
+ ++m_addressTableEntry;
+}
+
+const char* ImportedFunctionsEnumerator::currentFunctionName() const
+{
+ ASSERT(m_nameTableEntry);
+
+ // Ordinal imports have no name.
+ if (IMAGE_SNAP_BY_ORDINAL(m_nameTableEntry->u1.Ordinal))
+ return 0;
+
+ const IMAGE_IMPORT_BY_NAME* importByName = static_cast<const IMAGE_IMPORT_BY_NAME*>(m_image.convertRVAToAddress(m_nameTableEntry->u1.AddressOfData));
+ return reinterpret_cast<const char*>(importByName->Name);
+}
+
+const void* const* ImportedFunctionsEnumerator::addressOfCurrentFunctionPointer() const
+{
+ ASSERT(m_addressTableEntry);
+ COMPILE_ASSERT(sizeof(void*) == sizeof(m_addressTableEntry->u1.Function), FunctionAddressSizeMatchesPointerSize);
+ return reinterpret_cast<const void* const*>(&m_addressTableEntry->u1.Function);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/ImportedFunctionsEnumerator.h b/Source/WebCore/platform/win/ImportedFunctionsEnumerator.h
new file mode 100644
index 000000000..e8e0a0539
--- /dev/null
+++ b/Source/WebCore/platform/win/ImportedFunctionsEnumerator.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 ImportedFunctionsEnumerator_h
+#define ImportedFunctionsEnumerator_h
+
+#include "PEImage.h"
+
+namespace WebCore {
+
+// Enumerates the functions from a single module imported by the given PEImage.
+class ImportedFunctionsEnumerator {
+public:
+ explicit ImportedFunctionsEnumerator(const PEImage&, const IMAGE_THUNK_DATA* importNameTable, const IMAGE_THUNK_DATA* importAddressTable);
+
+ bool isAtEnd() const;
+ void next();
+
+ const char* currentFunctionName() const;
+ const void* const* addressOfCurrentFunctionPointer() const;
+
+private:
+ const DWORD& currentFunctionAddress() const;
+
+ PEImage m_image;
+
+ // These point to corresponding entries in the Import Name Table (INT) and Import Address Table
+ // (IAT) for a particular module. The INT and IAT are parallel arrays that are terminated by an
+ // all-0 entry.
+ const IMAGE_THUNK_DATA* m_nameTableEntry;
+ const IMAGE_THUNK_DATA* m_addressTableEntry;
+};
+
+} // namespace WebCore
+
+#endif // ImportedFunctionsEnumerator_h
diff --git a/Source/WebCore/platform/win/ImportedModulesEnumerator.cpp b/Source/WebCore/platform/win/ImportedModulesEnumerator.cpp
new file mode 100644
index 000000000..3543374fb
--- /dev/null
+++ b/Source/WebCore/platform/win/ImportedModulesEnumerator.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "ImportedModulesEnumerator.h"
+
+#include "ImportedFunctionsEnumerator.h"
+
+// See <http://msdn.microsoft.com/en-us/magazine/cc301808.aspx> and
+// <http://msdn.microsoft.com/en-us/windows/hardware/gg463119> for more information about the PE
+// image format.
+
+namespace WebCore {
+
+ImportedModulesEnumerator::ImportedModulesEnumerator(const PEImage& image)
+ : m_image(image)
+{
+ if (m_image.isValid())
+ m_descriptor = static_cast<const IMAGE_IMPORT_DESCRIPTOR*>(m_image.dataDirectoryEntryAddress(IMAGE_DIRECTORY_ENTRY_IMPORT));
+ else
+ m_descriptor = 0;
+}
+
+bool ImportedModulesEnumerator::isAtEnd() const
+{
+ return !m_descriptor || !m_descriptor->Characteristics;
+}
+
+void ImportedModulesEnumerator::next()
+{
+ ASSERT(!isAtEnd());
+ ++m_descriptor;
+}
+
+const char* ImportedModulesEnumerator::currentModuleName() const
+{
+ ASSERT(m_descriptor);
+ return static_cast<const char*>(m_image.convertRVAToAddress(m_descriptor->Name));
+}
+
+ImportedFunctionsEnumerator ImportedModulesEnumerator::functionsEnumerator() const
+{
+ ASSERT(m_descriptor);
+
+ const IMAGE_THUNK_DATA* importNameTable = static_cast<const IMAGE_THUNK_DATA*>(m_image.convertRVAToAddress(m_descriptor->OriginalFirstThunk));
+ const IMAGE_THUNK_DATA* importAddressTable = static_cast<const IMAGE_THUNK_DATA*>(m_image.convertRVAToAddress(m_descriptor->FirstThunk));
+
+ return ImportedFunctionsEnumerator(m_image, importNameTable, importAddressTable);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/ImportedModulesEnumerator.h b/Source/WebCore/platform/win/ImportedModulesEnumerator.h
new file mode 100644
index 000000000..da7342fbb
--- /dev/null
+++ b/Source/WebCore/platform/win/ImportedModulesEnumerator.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 ImportedModulesEnumerator_h
+#define ImportedModulesEnumerator_h
+
+#include "ImportedModulesEnumeratorBase.h"
+#include "PEImage.h"
+
+namespace WebCore {
+
+// Enumerates all non-delay-loaded modules imported by the given PEImage.
+class ImportedModulesEnumerator : public ImportedModulesEnumeratorBase {
+public:
+ explicit ImportedModulesEnumerator(const PEImage&);
+
+ virtual bool isAtEnd() const;
+ virtual void next();
+
+ virtual const char* currentModuleName() const;
+ virtual ImportedFunctionsEnumerator functionsEnumerator() const;
+
+private:
+ PEImage m_image;
+ const IMAGE_IMPORT_DESCRIPTOR* m_descriptor;
+};
+
+} // namespace WebCore
+
+#endif // ImportedModulesEnumerator_h
diff --git a/Source/WebCore/platform/win/ImportedModulesEnumeratorBase.h b/Source/WebCore/platform/win/ImportedModulesEnumeratorBase.h
new file mode 100644
index 000000000..9f7842b07
--- /dev/null
+++ b/Source/WebCore/platform/win/ImportedModulesEnumeratorBase.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 ImportedModulesEnumeratorBase_h
+#define ImportedModulesEnumeratorBase_h
+
+namespace WebCore {
+
+class ImportedFunctionsEnumerator;
+
+class ImportedModulesEnumeratorBase {
+public:
+ virtual bool isAtEnd() const = 0;
+ virtual void next() = 0;
+
+ virtual const char* currentModuleName() const = 0;
+ virtual ImportedFunctionsEnumerator functionsEnumerator() const = 0;
+
+protected:
+ virtual ~ImportedModulesEnumeratorBase() { }
+};
+
+} // namespace WebCore
+
+#endif // ImportedModulesEnumeratorBase_h
diff --git a/Source/WebCore/platform/win/KeyEventWin.cpp b/Source/WebCore/platform/win/KeyEventWin.cpp
new file mode 100644
index 000000000..59b2d2c62
--- /dev/null
+++ b/Source/WebCore/platform/win/KeyEventWin.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2006, 2007, 2010 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 "PlatformKeyboardEvent.h"
+
+#include <windows.h>
+#include <wtf/ASCIICType.h>
+
+#ifndef MAPVK_VSC_TO_VK_EX
+#define MAPVK_VSC_TO_VK_EX 3
+#endif
+
+using namespace WTF;
+
+namespace WebCore {
+
+static const unsigned short HIGH_BIT_MASK_SHORT = 0x8000;
+
+// FIXME: This is incomplete. We could change this to mirror
+// more like what Firefox does, and generate these switch statements
+// at build time.
+static String keyIdentifierForWindowsKeyCode(unsigned short keyCode)
+{
+ switch (keyCode) {
+ case VK_MENU:
+ return "Alt";
+ case VK_CONTROL:
+ return "Control";
+ case VK_SHIFT:
+ return "Shift";
+ case VK_CAPITAL:
+ return "CapsLock";
+ case VK_LWIN:
+ case VK_RWIN:
+ return "Win";
+ case VK_CLEAR:
+ return "Clear";
+ case VK_DOWN:
+ return "Down";
+ // "End"
+ case VK_END:
+ return "End";
+ // "Enter"
+ case VK_RETURN:
+ return "Enter";
+ case VK_EXECUTE:
+ return "Execute";
+ case VK_F1:
+ return "F1";
+ case VK_F2:
+ return "F2";
+ case VK_F3:
+ return "F3";
+ case VK_F4:
+ return "F4";
+ case VK_F5:
+ return "F5";
+ case VK_F6:
+ return "F6";
+ case VK_F7:
+ return "F7";
+ case VK_F8:
+ return "F8";
+ case VK_F9:
+ return "F9";
+ case VK_F10:
+ return "F11";
+ case VK_F12:
+ return "F12";
+ case VK_F13:
+ return "F13";
+ case VK_F14:
+ return "F14";
+ case VK_F15:
+ return "F15";
+ case VK_F16:
+ return "F16";
+ case VK_F17:
+ return "F17";
+ case VK_F18:
+ return "F18";
+ case VK_F19:
+ return "F19";
+ case VK_F20:
+ return "F20";
+ case VK_F21:
+ return "F21";
+ case VK_F22:
+ return "F22";
+ case VK_F23:
+ return "F23";
+ case VK_F24:
+ return "F24";
+ case VK_HELP:
+ return "Help";
+ case VK_HOME:
+ return "Home";
+ case VK_INSERT:
+ return "Insert";
+ case VK_LEFT:
+ return "Left";
+ case VK_NEXT:
+ return "PageDown";
+ case VK_PRIOR:
+ return "PageUp";
+ case VK_PAUSE:
+ return "Pause";
+ case VK_SNAPSHOT:
+ return "PrintScreen";
+ case VK_RIGHT:
+ return "Right";
+ case VK_SCROLL:
+ return "Scroll";
+ case VK_SELECT:
+ return "Select";
+ case VK_UP:
+ return "Up";
+ // Standard says that DEL becomes U+007F.
+ case VK_DELETE:
+ return "U+007F";
+ default:
+ return String::format("U+%04X", toASCIIUpper(keyCode));
+ }
+}
+
+static bool isKeypadEvent(WPARAM code, LPARAM keyData, PlatformEvent::Type type)
+{
+ if (type != PlatformEvent::RawKeyDown && type != PlatformEvent::KeyUp)
+ return false;
+
+ switch (code) {
+ case VK_NUMLOCK:
+ case VK_NUMPAD0:
+ case VK_NUMPAD1:
+ case VK_NUMPAD2:
+ case VK_NUMPAD3:
+ case VK_NUMPAD4:
+ case VK_NUMPAD5:
+ case VK_NUMPAD6:
+ case VK_NUMPAD7:
+ case VK_NUMPAD8:
+ case VK_NUMPAD9:
+ case VK_MULTIPLY:
+ case VK_ADD:
+ case VK_SEPARATOR:
+ case VK_SUBTRACT:
+ case VK_DECIMAL:
+ case VK_DIVIDE:
+ return true;
+ case VK_RETURN:
+ return HIWORD(keyData) & KF_EXTENDED;
+ case VK_INSERT:
+ case VK_DELETE:
+ case VK_PRIOR:
+ case VK_NEXT:
+ case VK_END:
+ case VK_HOME:
+ case VK_LEFT:
+ case VK_UP:
+ case VK_RIGHT:
+ case VK_DOWN:
+ return !(HIWORD(keyData) & KF_EXTENDED);
+ default:
+ return false;
+ }
+}
+
+static int windowsKeycodeWithLocation(WPARAM keycode, LPARAM keyData)
+{
+ if (keycode != VK_CONTROL && keycode != VK_MENU && keycode != VK_SHIFT)
+ return keycode;
+
+ // If we don't need to support Windows XP or older Windows,
+ // it might be better to use MapVirtualKeyEx with scancode and
+ // extended keycode (i.e. 0xe0 or 0xe1).
+ if ((keyData >> 16) & KF_EXTENDED) {
+ switch (keycode) {
+ case VK_CONTROL:
+ return VK_RCONTROL;
+ case VK_SHIFT:
+ return VK_RSHIFT;
+ case VK_MENU:
+ return VK_RMENU;
+ default:
+ break;
+ }
+ }
+
+ int scancode = (keyData >> 16) & 0xFF;
+ int regeneratedVirtualKeyCode = ::MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
+ return regeneratedVirtualKeyCode ? regeneratedVirtualKeyCode : keycode;
+}
+
+static inline String singleCharacterString(UChar c)
+{
+ return String(&c, 1);
+}
+
+PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData, Type type, bool systemKey)
+ : PlatformEvent(type, GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT, GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT, GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT, false, ::GetTickCount() * 0.001)
+ , m_text((type == PlatformEvent::Char) ? singleCharacterString(code) : String())
+ , m_unmodifiedText((type == PlatformEvent::Char) ? singleCharacterString(code) : String())
+ , m_keyIdentifier((type == PlatformEvent::Char) ? String() : keyIdentifierForWindowsKeyCode(code))
+ , m_windowsVirtualKeyCode((type == RawKeyDown || type == KeyUp) ? windowsKeycodeWithLocation(code, keyData) : 0)
+ , m_nativeVirtualKeyCode(m_windowsVirtualKeyCode)
+ , m_macCharCode(0)
+ , m_autoRepeat(HIWORD(keyData) & KF_REPEAT)
+ , m_isKeypad(isKeypadEvent(code, keyData, type))
+ , m_isSystemKey(systemKey)
+{
+}
+
+void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool)
+{
+ // No KeyDown events on Windows to disambiguate.
+ ASSERT_NOT_REACHED();
+}
+
+bool PlatformKeyboardEvent::currentCapsLockState()
+{
+ return GetKeyState(VK_CAPITAL) & 1;
+}
+
+void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey)
+{
+ shiftKey = GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT;
+ ctrlKey = GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT;
+ altKey = GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT;
+ metaKey = false;
+}
+
+}
diff --git a/Source/WebCore/platform/win/LanguageWin.cpp b/Source/WebCore/platform/win/LanguageWin.cpp
new file mode 100644
index 000000000..affd1d399
--- /dev/null
+++ b/Source/WebCore/platform/win/LanguageWin.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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 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 "Language.h"
+
+#include <windows.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static String localeInfo(LCTYPE localeType, const String& fallback)
+{
+ LANGID langID = GetUserDefaultUILanguage();
+ int localeChars = GetLocaleInfo(langID, localeType, 0, 0);
+ if (!localeChars)
+ return fallback;
+ UChar* localeNameBuf;
+ String localeName = String::createUninitialized(localeChars, localeNameBuf);
+ localeChars = GetLocaleInfo(langID, localeType, localeNameBuf, localeChars);
+ if (!localeChars)
+ return fallback;
+ if (localeName.isEmpty())
+ return fallback;
+
+ localeName.truncate(localeName.length() - 1);
+ return localeName;
+}
+
+static String platformLanguage()
+{
+ static String computedDefaultLanguage;
+ if (!computedDefaultLanguage.isEmpty())
+ return computedDefaultLanguage;
+
+ String languageName = localeInfo(LOCALE_SISO639LANGNAME, "en");
+ String countryName = localeInfo(LOCALE_SISO3166CTRYNAME, String());
+
+ if (countryName.isEmpty())
+ computedDefaultLanguage = languageName;
+ else
+ computedDefaultLanguage = languageName + '-' + countryName;
+
+ return computedDefaultLanguage;
+}
+
+Vector<String> platformUserPreferredLanguages()
+{
+ Vector<String> userPreferredLanguages;
+ userPreferredLanguages.append(platformLanguage());
+ return userPreferredLanguages;
+}
+
+}
diff --git a/Source/WebCore/platform/win/LocalizedStringsWin.cpp b/Source/WebCore/platform/win/LocalizedStringsWin.cpp
new file mode 100644
index 000000000..4dc698b96
--- /dev/null
+++ b/Source/WebCore/platform/win/LocalizedStringsWin.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "LocalizedStrings.h"
+
+#include "WebCoreInstanceHandle.h"
+#include <windows.h>
+#include <wtf/Assertions.h>
+#include <wtf/MainThread.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/WTFString.h>
+
+#if USE(CF)
+#include "WebCoreBundleWin.h"
+#include <CoreFoundation/CFBundle.h>
+#include <wtf/RetainPtr.h>
+#endif
+
+namespace WebCore {
+
+String localizedString(const char* key)
+{
+ ASSERT(isMainThread());
+
+#if USE(CF)
+ static CFStringRef notFound = CFSTR("localized string not found");
+
+ RetainPtr<CFStringRef> keyString = adoptCF(CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingUTF8, kCFAllocatorNull));
+ RetainPtr<CFStringRef> result = adoptCF(CFCopyLocalizedStringWithDefaultValue(keyString.get(), 0, webKitBundle(), notFound, 0));
+ ASSERT_WITH_MESSAGE(result.get() != notFound, "could not find localizable string %s in bundle", key);
+
+ return result.get();
+#else
+ // FIXME: Implement localizedString() for !USE(CF).
+ return String::fromUTF8(key, strlen(key));
+#endif
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/LoggingWin.cpp b/Source/WebCore/platform/win/LoggingWin.cpp
new file mode 100644
index 000000000..f36a14160
--- /dev/null
+++ b/Source/WebCore/platform/win/LoggingWin.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008, 2013 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 "Logging.h"
+
+#if !LOG_DISABLED
+
+#include <windows.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static char * const loggingEnvironmentVariable = "WebCoreLogging";
+
+String logLevelString()
+{
+ DWORD length = GetEnvironmentVariableA(loggingEnvironmentVariable, 0, 0);
+ if (!length)
+ return emptyString();
+
+ auto buffer = std::make_unique<char[]>(length);
+
+ if (!GetEnvironmentVariableA(loggingEnvironmentVariable, buffer.get(), length))
+ return emptyString();
+
+ return String(buffer.get());
+}
+
+} // namespace WebCore
+
+#endif // !LOG_DISABLED
diff --git a/Source/WebCore/platform/win/MIMETypeRegistryWin.cpp b/Source/WebCore/platform/win/MIMETypeRegistryWin.cpp
new file mode 100644
index 000000000..73a6270fc
--- /dev/null
+++ b/Source/WebCore/platform/win/MIMETypeRegistryWin.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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 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 "MIMETypeRegistry.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/MainThread.h>
+#include <wtf/WindowsExtras.h>
+
+namespace WebCore {
+
+static String mimeTypeForExtension(const String& extension)
+{
+ String ext = "." + extension;
+ WCHAR contentTypeStr[256];
+ DWORD contentTypeStrLen = sizeof(contentTypeStr);
+ DWORD keyType;
+
+ HRESULT result = getRegistryValue(HKEY_CLASSES_ROOT, ext.charactersWithNullTermination().data(), L"Content Type", &keyType, contentTypeStr, &contentTypeStrLen);
+
+ if (result == ERROR_SUCCESS && keyType == REG_SZ)
+ return String(contentTypeStr, contentTypeStrLen / sizeof(contentTypeStr[0]) - 1);
+
+ return String();
+}
+
+String MIMETypeRegistry::getPreferredExtensionForMIMEType(const String& type)
+{
+ String path = "MIME\\Database\\Content Type\\" + type;
+ WCHAR extStr[MAX_PATH];
+ DWORD extStrLen = sizeof(extStr);
+ DWORD keyType;
+
+ HRESULT result = getRegistryValue(HKEY_CLASSES_ROOT, path.charactersWithNullTermination().data(), L"Extension", &keyType, extStr, &extStrLen);
+
+ if (result == ERROR_SUCCESS && keyType == REG_SZ)
+ return String(extStr + 1, extStrLen / sizeof(extStr[0]) - 2);
+
+ return String();
+}
+
+String MIMETypeRegistry::getMIMETypeForExtension(const String &ext)
+{
+ ASSERT(isMainThread());
+
+ if (ext.isEmpty())
+ return String();
+
+ static HashMap<String, String> mimetypeMap;
+ if (mimetypeMap.isEmpty()) {
+ //fill with initial values
+ mimetypeMap.add("txt", "text/plain");
+ mimetypeMap.add("pdf", "application/pdf");
+ mimetypeMap.add("ps", "application/postscript");
+ mimetypeMap.add("html", "text/html");
+ mimetypeMap.add("htm", "text/html");
+ mimetypeMap.add("xml", "text/xml");
+ mimetypeMap.add("xsl", "text/xsl");
+ mimetypeMap.add("js", "application/x-javascript");
+ mimetypeMap.add("xhtml", "application/xhtml+xml");
+ mimetypeMap.add("rss", "application/rss+xml");
+ mimetypeMap.add("webarchive", "application/x-webarchive");
+ mimetypeMap.add("svg", "image/svg+xml");
+ mimetypeMap.add("svgz", "image/svg+xml");
+ mimetypeMap.add("jpg", "image/jpeg");
+ mimetypeMap.add("jpeg", "image/jpeg");
+ mimetypeMap.add("png", "image/png");
+ mimetypeMap.add("tif", "image/tiff");
+ mimetypeMap.add("tiff", "image/tiff");
+ mimetypeMap.add("ico", "image/ico");
+ mimetypeMap.add("cur", "image/ico");
+ mimetypeMap.add("bmp", "image/bmp");
+ mimetypeMap.add("wml", "text/vnd.wap.wml");
+ mimetypeMap.add("wmlc", "application/vnd.wap.wmlc");
+ mimetypeMap.add("m4a", "audio/x-m4a");
+ }
+ String result = mimetypeMap.get(ext);
+ if (result.isEmpty()) {
+ result = mimeTypeForExtension(ext);
+ if (!result.isEmpty())
+ mimetypeMap.add(ext, result);
+ }
+ return result;
+}
+
+bool MIMETypeRegistry::isApplicationPluginMIMEType(const String&)
+{
+ return false;
+}
+
+}
diff --git a/Source/WebCore/platform/win/MainThreadSharedTimerWin.cpp b/Source/WebCore/platform/win/MainThreadSharedTimerWin.cpp
new file mode 100644
index 000000000..9a660db01
--- /dev/null
+++ b/Source/WebCore/platform/win/MainThreadSharedTimerWin.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2006 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 "MainThreadSharedTimer.h"
+
+#include "Page.h"
+#include "Settings.h"
+#include "WebCoreInstanceHandle.h"
+#include "Widget.h"
+#include <wtf/Assertions.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/WindowsExtras.h>
+
+#include <mmsystem.h>
+
+// These aren't in winuser.h with the MSVS 2003 Platform SDK,
+// so use default values in that case.
+#ifndef USER_TIMER_MINIMUM
+#define USER_TIMER_MINIMUM 0x0000000A
+#endif
+
+#ifndef USER_TIMER_MAXIMUM
+#define USER_TIMER_MAXIMUM 0x7FFFFFFF
+#endif
+
+#ifndef QS_RAWINPUT
+#define QS_RAWINPUT 0x0400
+#endif
+
+namespace WebCore {
+
+static UINT timerID;
+
+static HANDLE timer;
+static HWND timerWindowHandle = 0;
+const LPCWSTR kTimerWindowClassName = L"TimerWindowClass";
+
+static UINT timerFiredMessage = 0;
+static HANDLE timerQueue;
+static bool highResTimerActive;
+static bool processingCustomTimerMessage = false;
+static LONG pendingTimers;
+
+const int timerResolution = 1; // To improve timer resolution, we call timeBeginPeriod/timeEndPeriod with this value to increase timer resolution to 1ms.
+const int highResolutionThresholdMsec = 16; // Only activate high-res timer for sub-16ms timers (Windows can fire timers at 16ms intervals without changing the system resolution).
+const int stopHighResTimerInMsec = 300; // Stop high-res timer after 0.3 seconds to lessen power consumption (we don't use a smaller time since oscillating between high and low resolution breaks timer accuracy on XP).
+
+enum {
+ sharedTimerID = 1000,
+ endHighResTimerID = 1001,
+};
+
+LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (message == WM_TIMER) {
+ if (wParam == sharedTimerID) {
+ KillTimer(timerWindowHandle, sharedTimerID);
+ MainThreadSharedTimer::singleton().fired();
+ } else if (wParam == endHighResTimerID) {
+ KillTimer(timerWindowHandle, endHighResTimerID);
+ highResTimerActive = false;
+ timeEndPeriod(timerResolution);
+ }
+ } else if (message == timerFiredMessage) {
+ InterlockedExchange(&pendingTimers, 0);
+ processingCustomTimerMessage = true;
+ MainThreadSharedTimer::singleton().fired();
+ processingCustomTimerMessage = false;
+ } else
+ return DefWindowProc(hWnd, message, wParam, lParam);
+
+ return 0;
+}
+
+static void initializeOffScreenTimerWindow()
+{
+ if (timerWindowHandle)
+ return;
+
+ WNDCLASSEX wcex;
+ memset(&wcex, 0, sizeof(WNDCLASSEX));
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.lpfnWndProc = TimerWindowWndProc;
+ wcex.hInstance = WebCore::instanceHandle();
+ wcex.lpszClassName = kTimerWindowClassName;
+ RegisterClassEx(&wcex);
+
+ timerWindowHandle = CreateWindow(kTimerWindowClassName, 0, 0,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, WebCore::instanceHandle(), 0);
+
+ timerFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.TimerFired");
+}
+
+static void NTAPI queueTimerProc(PVOID, BOOLEAN)
+{
+ if (InterlockedIncrement(&pendingTimers) == 1)
+ PostMessage(timerWindowHandle, timerFiredMessage, 0, 0);
+}
+
+void MainThreadSharedTimer::setFireInterval(double interval)
+{
+ ASSERT(m_firedFunction);
+
+ unsigned intervalInMS;
+ interval *= 1000;
+ if (interval > USER_TIMER_MAXIMUM)
+ intervalInMS = USER_TIMER_MAXIMUM;
+ else
+ intervalInMS = static_cast<unsigned>(interval);
+
+ initializeOffScreenTimerWindow();
+ bool timerSet = false;
+
+ if (Settings::shouldUseHighResolutionTimers()) {
+ if (interval < highResolutionThresholdMsec) {
+ if (!highResTimerActive) {
+ highResTimerActive = true;
+ timeBeginPeriod(timerResolution);
+ }
+ SetTimer(timerWindowHandle, endHighResTimerID, stopHighResTimerInMsec, 0);
+ }
+
+ DWORD queueStatus = LOWORD(GetQueueStatus(QS_PAINT | QS_MOUSEBUTTON | QS_KEY | QS_RAWINPUT));
+
+ // Win32 has a tri-level queue with application messages > user input > WM_PAINT/WM_TIMER.
+
+ // If the queue doesn't contains input events, we use a higher priorty timer event posting mechanism.
+ if (!(queueStatus & (QS_MOUSEBUTTON | QS_KEY | QS_RAWINPUT))) {
+ if (intervalInMS < USER_TIMER_MINIMUM && !processingCustomTimerMessage && !(queueStatus & QS_PAINT)) {
+ // Call PostMessage immediately if the timer is already expired, unless a paint is pending.
+ // (we prioritize paints over timers)
+ if (InterlockedIncrement(&pendingTimers) == 1)
+ PostMessage(timerWindowHandle, timerFiredMessage, 0, 0);
+ timerSet = true;
+ } else {
+ // Otherwise, delay the PostMessage via a CreateTimerQueueTimer
+ if (!timerQueue)
+ timerQueue = CreateTimerQueue();
+ if (timer)
+ DeleteTimerQueueTimer(timerQueue, timer, 0);
+ timerSet = CreateTimerQueueTimer(&timer, timerQueue, queueTimerProc, 0, intervalInMS, 0, WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE);
+ }
+ }
+ }
+
+ if (timerSet) {
+ if (timerID) {
+ KillTimer(timerWindowHandle, timerID);
+ timerID = 0;
+ }
+ } else {
+ timerID = SetTimer(timerWindowHandle, sharedTimerID, intervalInMS, 0);
+ timer = 0;
+ }
+}
+
+void MainThreadSharedTimer::stop()
+{
+ if (timerQueue && timer) {
+ DeleteTimerQueueTimer(timerQueue, timer, 0);
+ timer = 0;
+ }
+
+ if (timerID) {
+ KillTimer(timerWindowHandle, timerID);
+ timerID = 0;
+ }
+}
+
+void MainThreadSharedTimer::invalidate()
+{
+}
+
+}
diff --git a/Source/WebCore/platform/win/MemoryPressureHandlerWin.cpp b/Source/WebCore/platform/win/MemoryPressureHandlerWin.cpp
new file mode 100644
index 000000000..0d523b88a
--- /dev/null
+++ b/Source/WebCore/platform/win/MemoryPressureHandlerWin.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2015 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 "MemoryPressureHandler.h"
+
+#include <WebCore/Timer.h>
+#include <WebCore/Win32Handle.h>
+#include <psapi.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+// We create a timer for checking the memory usage at regular intervals.
+
+class CheckMemoryTimer : public TimerBase {
+public:
+ CheckMemoryTimer(MemoryPressureHandler&);
+
+private:
+ virtual void fired();
+
+ void handleMemoryLow();
+
+ MemoryPressureHandler& m_pressureHandler;
+ Win32Handle m_lowMemoryHandle;
+};
+
+CheckMemoryTimer::CheckMemoryTimer(MemoryPressureHandler& pressureHandler)
+ : m_pressureHandler(pressureHandler)
+{
+ m_lowMemoryHandle = CreateMemoryResourceNotification(LowMemoryResourceNotification);
+}
+
+void CheckMemoryTimer::fired()
+{
+ m_pressureHandler.setUnderMemoryPressure(false);
+
+ BOOL memoryLow;
+
+ if (QueryMemoryResourceNotification(m_lowMemoryHandle.get(), &memoryLow) && memoryLow) {
+ handleMemoryLow();
+ return;
+ }
+
+#if CPU(X86)
+ PROCESS_MEMORY_COUNTERS_EX counters;
+
+ if (!GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&counters), sizeof(counters)))
+ return;
+
+ // On Windows, 32-bit processes have 2GB of memory available, where some is used by the system.
+ // Debugging has shown that allocations might fail and cause crashes when memory usage is > ~1GB.
+ const int maxMemoryUsageBytes = 1024 * 1024 * 1024;
+
+ if (counters.PrivateUsage > maxMemoryUsageBytes)
+ handleMemoryLow();
+#endif
+}
+
+void CheckMemoryTimer::handleMemoryLow()
+{
+ m_pressureHandler.setUnderMemoryPressure(true);
+ m_pressureHandler.releaseMemory(Critical::Yes);
+}
+
+void MemoryPressureHandler::platformReleaseMemory(Critical)
+{
+}
+
+static std::unique_ptr<CheckMemoryTimer>& memCheckTimer()
+{
+ static NeverDestroyed<std::unique_ptr<CheckMemoryTimer>> memCheckTimer;
+ return memCheckTimer;
+}
+
+void MemoryPressureHandler::install()
+{
+ m_installed = true;
+ memCheckTimer() = std::make_unique<CheckMemoryTimer>(*this);
+ memCheckTimer()->startRepeating(60.0);
+}
+
+void MemoryPressureHandler::uninstall()
+{
+ if (!m_installed)
+ return;
+
+ memCheckTimer() = nullptr;
+ m_installed = false;
+}
+
+void MemoryPressureHandler::holdOff(unsigned seconds)
+{
+}
+
+void MemoryPressureHandler::respondToMemoryPressure(Critical critical, Synchronous synchronous)
+{
+ uninstall();
+
+ m_lowMemoryHandler(critical, synchronous);
+}
+
+size_t MemoryPressureHandler::ReliefLogger::platformMemoryUsage()
+{
+ return 0;
+}
+
+void MemoryPressureHandler::ReliefLogger::platformLog()
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PEImage.cpp b/Source/WebCore/platform/win/PEImage.cpp
new file mode 100644
index 000000000..abea4fbf8
--- /dev/null
+++ b/Source/WebCore/platform/win/PEImage.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "PEImage.h"
+
+// See <http://msdn.microsoft.com/en-us/magazine/cc301808.aspx> and
+// <http://msdn.microsoft.com/en-us/windows/hardware/gg463119> for more information about the PE
+// image format.
+
+namespace WebCore {
+
+PEImage::PEImage(HMODULE module)
+ : m_module(module)
+ , m_ntHeaders(0)
+{
+ const IMAGE_DOS_HEADER* dosHeader = reinterpret_cast<const IMAGE_DOS_HEADER*>(m_module);
+ if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ return;
+
+ const IMAGE_NT_HEADERS* ntHeaders = static_cast<const IMAGE_NT_HEADERS*>(convertRVAToAddress(dosHeader->e_lfanew));
+ if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
+ return;
+
+ if (ntHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+ return;
+
+ m_ntHeaders = ntHeaders;
+}
+
+const void* PEImage::convertRVAToAddress(DWORD rva) const
+{
+ return reinterpret_cast<unsigned char*>(m_module) + rva;
+}
+
+const void* PEImage::dataDirectoryEntryAddress(DWORD entryIndex) const
+{
+ if (!isValid())
+ return 0;
+
+ if (m_ntHeaders->OptionalHeader.NumberOfRvaAndSizes <= entryIndex)
+ return 0;
+
+ const IMAGE_DATA_DIRECTORY& directory = m_ntHeaders->OptionalHeader.DataDirectory[entryIndex];
+
+ if (!directory.Size)
+ return 0;
+
+ return convertRVAToAddress(directory.VirtualAddress);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PEImage.h b/Source/WebCore/platform/win/PEImage.h
new file mode 100644
index 000000000..50c534d6d
--- /dev/null
+++ b/Source/WebCore/platform/win/PEImage.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 PEImage_h
+#define PEImage_h
+
+#include <windows.h>
+
+namespace WebCore {
+
+class PEImage {
+public:
+ explicit PEImage(HMODULE);
+
+ bool isValid() const { return m_ntHeaders; }
+
+ // A relative virtual address (RVA) is an address relative to the base of the image. This
+ // function will convert an RVA to an non-relative address, which can then be dereferenced.
+ const void* convertRVAToAddress(DWORD) const;
+
+ // Returns the address of the data corresponding to the given entry in the image's
+ // DataDirectory.
+ const void* dataDirectoryEntryAddress(DWORD entryIndex) const;
+
+private:
+ HMODULE m_module;
+ const IMAGE_NT_HEADERS* m_ntHeaders;
+};
+
+} // namespace WebCore
+
+#endif // PEImage_h
diff --git a/Source/WebCore/platform/win/PasteboardWin.cpp b/Source/WebCore/platform/win/PasteboardWin.cpp
new file mode 100644
index 000000000..031bfd249
--- /dev/null
+++ b/Source/WebCore/platform/win/PasteboardWin.cpp
@@ -0,0 +1,1060 @@
+/*
+ * Copyright (C) 2006, 2007, 2013-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Xueqing Huang <huangxueqing@baidu.com>
+ *
+ * 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 "Pasteboard.h"
+
+#include "BitmapInfo.h"
+#include "CachedImage.h"
+#include "ClipboardUtilitiesWin.h"
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Editor.h"
+#include "Element.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "HWndDC.h"
+#include "HitTestResult.h"
+#include "Image.h"
+#include "URL.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "Range.h"
+#include "RenderImage.h"
+#include "SharedBuffer.h"
+#include "TextEncoding.h"
+#include "WebCoreInstanceHandle.h"
+#include "markup.h"
+#include <wtf/WindowsExtras.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringView.h>
+#include <wtf/win/GDIObject.h>
+
+namespace WebCore {
+
+// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
+// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
+
+static UINT HTMLClipboardFormat = 0;
+static UINT BookmarkClipboardFormat = 0;
+static UINT WebSmartPasteFormat = 0;
+
+static LRESULT CALLBACK PasteboardOwnerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lresult = 0;
+
+ switch (message) {
+ case WM_RENDERFORMAT:
+ // This message comes when SetClipboardData was sent a null data handle
+ // and now it's come time to put the data on the clipboard.
+ break;
+ case WM_RENDERALLFORMATS:
+ // This message comes when SetClipboardData was sent a null data handle
+ // and now this application is about to quit, so it must put data on
+ // the clipboard before it exits.
+ break;
+ case WM_DESTROY:
+ break;
+ case WM_DRAWCLIPBOARD:
+ break;
+ case WM_CHANGECBCHAIN:
+ break;
+ default:
+ lresult = DefWindowProc(hWnd, message, wParam, lParam);
+ break;
+ }
+ return lresult;
+}
+
+std::unique_ptr<Pasteboard> Pasteboard::createForCopyAndPaste()
+{
+ auto pasteboard = std::make_unique<Pasteboard>();
+ COMPtr<IDataObject> clipboardData;
+ if (!SUCCEEDED(OleGetClipboard(&clipboardData)))
+ clipboardData = 0;
+ pasteboard->setExternalDataObject(clipboardData.get());
+ return pasteboard;
+}
+
+std::unique_ptr<Pasteboard> Pasteboard::createPrivate()
+{
+ // Windows has no "Private pasteboard" concept.
+ return createForCopyAndPaste();
+}
+
+#if ENABLE(DRAG_SUPPORT)
+std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop()
+{
+ COMPtr<WCDataObject> dataObject;
+ WCDataObject::createInstance(&dataObject);
+ return std::make_unique<Pasteboard>(dataObject.get());
+}
+
+// static
+std::unique_ptr<Pasteboard> Pasteboard::createForDragAndDrop(const DragData& dragData)
+{
+ if (dragData.platformData())
+ return std::make_unique<Pasteboard>(dragData.platformData());
+ // FIXME: Should add a const overload of dragDataMap so we don't need a const_cast here.
+ return std::make_unique<Pasteboard>(const_cast<DragData&>(dragData).dragDataMap());
+}
+#endif
+
+void Pasteboard::finishCreatingPasteboard()
+{
+ WNDCLASS wc;
+ memset(&wc, 0, sizeof(WNDCLASS));
+ wc.lpfnWndProc = PasteboardOwnerWndProc;
+ wc.hInstance = WebCore::instanceHandle();
+ wc.lpszClassName = L"PasteboardOwnerWindowClass";
+ RegisterClass(&wc);
+
+ m_owner = ::CreateWindow(L"PasteboardOwnerWindowClass", L"PasteboardOwnerWindow", 0, 0, 0, 0, 0,
+ HWND_MESSAGE, 0, 0, 0);
+
+ HTMLClipboardFormat = ::RegisterClipboardFormat(L"HTML Format");
+ BookmarkClipboardFormat = ::RegisterClipboardFormat(L"UniformResourceLocatorW");
+ WebSmartPasteFormat = ::RegisterClipboardFormat(L"WebKit Smart Paste Format");
+}
+
+Pasteboard::Pasteboard()
+ : m_dataObject(0)
+ , m_writableDataObject(0)
+{
+ finishCreatingPasteboard();
+}
+
+Pasteboard::Pasteboard(IDataObject* dataObject)
+ : m_dataObject(dataObject)
+ , m_writableDataObject(0)
+{
+ finishCreatingPasteboard();
+}
+
+Pasteboard::Pasteboard(WCDataObject* dataObject)
+ : m_dataObject(dataObject)
+ , m_writableDataObject(dataObject)
+{
+ finishCreatingPasteboard();
+}
+
+Pasteboard::Pasteboard(const DragDataMap& dataMap)
+ : m_dataObject(0)
+ , m_writableDataObject(0)
+ , m_dragDataMap(dataMap)
+{
+ finishCreatingPasteboard();
+}
+
+void Pasteboard::clear()
+{
+ if (::OpenClipboard(m_owner)) {
+ ::EmptyClipboard();
+ ::CloseClipboard();
+ }
+}
+
+enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText, ClipboardDataTypeTextHTML };
+
+static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
+{
+ String strippedType = type.stripWhiteSpace();
+
+ // two special cases for IE compatibility
+ if (equalLettersIgnoringASCIICase(strippedType, "text") || equalLettersIgnoringASCIICase(strippedType, "text/plain") || strippedType.startsWith("text/plain;", false))
+ return ClipboardDataTypeText;
+ if (equalLettersIgnoringASCIICase(strippedType, "url") || equalLettersIgnoringASCIICase(strippedType, "text/uri-list"))
+ return ClipboardDataTypeURL;
+ if (equalLettersIgnoringASCIICase(strippedType, "text/html"))
+ return ClipboardDataTypeTextHTML;
+
+ return ClipboardDataTypeNone;
+}
+
+void Pasteboard::clear(const String& type)
+{
+ if (!m_writableDataObject)
+ return;
+
+ ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
+
+ if (dataType == ClipboardDataTypeURL) {
+ m_writableDataObject->clearData(urlWFormat()->cfFormat);
+ m_writableDataObject->clearData(urlFormat()->cfFormat);
+ }
+ if (dataType == ClipboardDataTypeText) {
+ m_writableDataObject->clearData(plainTextFormat()->cfFormat);
+ m_writableDataObject->clearData(plainTextWFormat()->cfFormat);
+ }
+}
+
+bool Pasteboard::hasData()
+{
+ if (!m_dataObject && m_dragDataMap.isEmpty())
+ return false;
+
+ if (m_dataObject) {
+ COMPtr<IEnumFORMATETC> itr;
+ if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
+ return false;
+
+ if (!itr)
+ return false;
+
+ FORMATETC data;
+
+ // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
+ if (itr->Next(1, &data, 0) == S_OK) {
+ // There is at least one item in the IDataObject
+ return true;
+ }
+
+ return false;
+ }
+ return !m_dragDataMap.isEmpty();
+}
+
+static void addMimeTypesForFormat(ListHashSet<String>& results, const FORMATETC& format)
+{
+ // URL and Text are provided for compatibility with IE's model
+ if (format.cfFormat == urlFormat()->cfFormat || format.cfFormat == urlWFormat()->cfFormat) {
+ results.add("URL");
+ results.add("text/uri-list");
+ }
+
+ if (format.cfFormat == plainTextWFormat()->cfFormat || format.cfFormat == plainTextFormat()->cfFormat) {
+ results.add("Text");
+ results.add("text/plain");
+ }
+}
+
+Vector<String> Pasteboard::types()
+{
+ ListHashSet<String> results;
+
+ if (!m_dataObject && m_dragDataMap.isEmpty())
+ return Vector<String>();
+
+ if (m_dataObject) {
+ COMPtr<IEnumFORMATETC> itr;
+
+ if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
+ return Vector<String>();
+
+ if (!itr)
+ return Vector<String>();
+
+ FORMATETC data;
+
+ // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
+ while (itr->Next(1, &data, 0) == S_OK)
+ addMimeTypesForFormat(results, data);
+ } else {
+ for (DragDataMap::const_iterator it = m_dragDataMap.begin(); it != m_dragDataMap.end(); ++it) {
+ FORMATETC data;
+ data.cfFormat = (*it).key;
+ addMimeTypesForFormat(results, data);
+ }
+ }
+
+ Vector<String> vector;
+ copyToVector(results, vector);
+ return vector;
+}
+
+String Pasteboard::readString(const String& type)
+{
+ if (!m_dataObject && m_dragDataMap.isEmpty())
+ return "";
+
+ ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
+ if (dataType == ClipboardDataTypeText)
+ return m_dataObject ? getPlainText(m_dataObject.get()) : getPlainText(&m_dragDataMap);
+ if (dataType == ClipboardDataTypeURL)
+ return m_dataObject ? getURL(m_dataObject.get(), DragData::DoNotConvertFilenames) : getURL(&m_dragDataMap, DragData::DoNotConvertFilenames);
+ if (dataType == ClipboardDataTypeTextHTML) {
+ String data = m_dataObject ? getTextHTML(m_dataObject.get()) : getTextHTML(&m_dragDataMap);
+ if (!data.isEmpty())
+ return data;
+ return m_dataObject ? getCFHTML(m_dataObject.get()) : getCFHTML(&m_dragDataMap);
+ }
+
+ return "";
+}
+
+Vector<String> Pasteboard::readFilenames()
+{
+ Vector<String> fileNames;
+
+#if USE(CF)
+ if (m_dataObject) {
+ STGMEDIUM medium;
+ if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium)))
+ return fileNames;
+
+ HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
+ if (!hdrop)
+ return fileNames;
+
+ WCHAR filename[MAX_PATH];
+ UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
+ for (UINT i = 0; i < fileCount; i++) {
+ if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
+ continue;
+ fileNames.append(filename);
+ }
+
+ GlobalUnlock(medium.hGlobal);
+ ReleaseStgMedium(&medium);
+ return fileNames;
+ }
+ if (!m_dragDataMap.contains(cfHDropFormat()->cfFormat))
+ return fileNames;
+ return m_dragDataMap.get(cfHDropFormat()->cfFormat);
+#else
+ notImplemented();
+ return fileNames;
+#endif
+}
+
+static bool writeURL(WCDataObject *data, const URL& url, String title, bool withPlainText, bool withHTML)
+{
+ ASSERT(data);
+
+ if (url.isEmpty())
+ return false;
+
+ if (title.isEmpty()) {
+ title = url.lastPathComponent();
+ if (title.isEmpty())
+ title = url.host();
+ }
+
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ medium.hGlobal = createGlobalData(url, title);
+ bool success = false;
+ if (medium.hGlobal && FAILED(data->SetData(urlWFormat(), &medium, TRUE)))
+ ::GlobalFree(medium.hGlobal);
+ else
+ success = true;
+
+ if (withHTML) {
+ Vector<char> cfhtmlData;
+ markupToCFHTML(urlToMarkup(url, title), "", cfhtmlData);
+ medium.hGlobal = createGlobalData(cfhtmlData);
+ if (medium.hGlobal && FAILED(data->SetData(htmlFormat(), &medium, TRUE)))
+ ::GlobalFree(medium.hGlobal);
+ else
+ success = true;
+ }
+
+ if (withPlainText) {
+ medium.hGlobal = createGlobalData(url.string());
+ if (medium.hGlobal && FAILED(data->SetData(plainTextWFormat(), &medium, TRUE)))
+ ::GlobalFree(medium.hGlobal);
+ else
+ success = true;
+ }
+
+ return success;
+}
+
+void Pasteboard::writeString(const String& type, const String& data)
+{
+ if (!m_writableDataObject)
+ return;
+
+ ClipboardDataType winType = clipboardTypeFromMIMEType(type);
+
+ if (winType == ClipboardDataTypeURL) {
+ WebCore::writeURL(m_writableDataObject.get(), URL(URL(), data), String(), false, true);
+ return;
+ }
+
+ if (winType == ClipboardDataTypeText) {
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+ medium.hGlobal = createGlobalData(data);
+ if (!medium.hGlobal)
+ return;
+
+ if (FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
+ ::GlobalFree(medium.hGlobal);
+ }
+}
+
+#if ENABLE(DRAG_SUPPORT)
+void Pasteboard::setDragImage(DragImageRef, const IntPoint&)
+{
+ // Do nothing in Windows.
+}
+#endif
+
+void Pasteboard::writeRangeToDataObject(Range& selectedRange, Frame& frame)
+{
+ if (!m_writableDataObject)
+ return;
+
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ Vector<char> data;
+ markupToCFHTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
+ selectedRange.startContainer().document().url().string(), data);
+ medium.hGlobal = createGlobalData(data);
+ if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
+ ::GlobalFree(medium.hGlobal);
+
+ String str = frame.editor().selectedTextForDataTransfer();
+ replaceNewlinesWithWindowsStyleNewlines(str);
+ replaceNBSPWithSpace(str);
+ medium.hGlobal = createGlobalData(str);
+ if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
+ ::GlobalFree(medium.hGlobal);
+
+ medium.hGlobal = 0;
+ if (frame.editor().canSmartCopyOrDelete())
+ m_writableDataObject->SetData(smartPasteFormat(), &medium, TRUE);
+}
+
+void Pasteboard::writeSelection(Range& selectedRange, bool canSmartCopyOrDelete, Frame& frame, ShouldSerializeSelectedTextForDataTransfer shouldSerializeSelectedTextForDataTransfer)
+{
+ clear();
+
+ // Put CF_HTML format on the pasteboard
+ if (::OpenClipboard(m_owner)) {
+ Vector<char> data;
+ markupToCFHTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
+ selectedRange.startContainer().document().url().string(), data);
+ HGLOBAL cbData = createGlobalData(data);
+ if (!::SetClipboardData(HTMLClipboardFormat, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well
+ String str = shouldSerializeSelectedTextForDataTransfer == IncludeImageAltTextForDataTransfer ? frame.editor().selectedTextForDataTransfer() : frame.editor().selectedText();
+ replaceNewlinesWithWindowsStyleNewlines(str);
+ replaceNBSPWithSpace(str);
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(str);
+ if (!::SetClipboardData(CF_UNICODETEXT, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // enable smart-replacing later on by putting dummy data on the pasteboard
+ if (canSmartCopyOrDelete) {
+ if (::OpenClipboard(m_owner)) {
+ ::SetClipboardData(WebSmartPasteFormat, 0);
+ ::CloseClipboard();
+ }
+ }
+
+ writeRangeToDataObject(selectedRange, frame);
+}
+
+void Pasteboard::writePlainTextToDataObject(const String& text, SmartReplaceOption smartReplaceOption)
+{
+ if (!m_writableDataObject)
+ return;
+
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ String str = text;
+ replaceNewlinesWithWindowsStyleNewlines(str);
+ replaceNBSPWithSpace(str);
+ medium.hGlobal = createGlobalData(str);
+ if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
+ ::GlobalFree(medium.hGlobal);
+}
+
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
+{
+ clear();
+
+ // Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well
+ String str = text;
+ replaceNewlinesWithWindowsStyleNewlines(str);
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(str);
+ if (!::SetClipboardData(CF_UNICODETEXT, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // enable smart-replacing later on by putting dummy data on the pasteboard
+ if (smartReplaceOption == CanSmartReplace) {
+ if (::OpenClipboard(m_owner)) {
+ ::SetClipboardData(WebSmartPasteFormat, 0);
+ ::CloseClipboard();
+ }
+ }
+
+ writePlainTextToDataObject(text, smartReplaceOption);
+}
+
+static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length)
+{
+ size_t writeTo = 0;
+ size_t readFrom = 0;
+ while (readFrom < length) {
+ UINT type = PathGetCharType(psz[readFrom]);
+ if (!psz[readFrom] || type & (GCT_LFNCHAR | GCT_SHORTCHAR))
+ psz[writeTo++] = psz[readFrom];
+
+ readFrom++;
+ }
+ psz[writeTo] = 0;
+}
+
+static String filesystemPathFromUrlOrTitle(const String& url, const String& title, const UChar* extension, bool isLink)
+{
+ static const size_t fsPathMaxLengthExcludingNullTerminator = MAX_PATH - 1;
+ bool usedURL = false;
+ WCHAR fsPathBuffer[MAX_PATH];
+ fsPathBuffer[0] = 0;
+ int extensionLen = extension ? lstrlen(extension) : 0;
+ int fsPathMaxLengthExcludingExtension = fsPathMaxLengthExcludingNullTerminator - extensionLen;
+
+ if (!title.isEmpty()) {
+ size_t len = std::min<size_t>(title.length(), fsPathMaxLengthExcludingExtension);
+ StringView(title).substring(0, len).getCharactersWithUpconvert(fsPathBuffer);
+ fsPathBuffer[len] = 0;
+ pathRemoveBadFSCharacters(fsPathBuffer, len);
+ }
+
+ if (!lstrlen(fsPathBuffer)) {
+ URL kurl(URL(), url);
+ usedURL = true;
+ // The filename for any content based drag or file url should be the last element of
+ // the path. If we can't find it, or we're coming up with the name for a link
+ // we just use the entire url.
+ DWORD len = fsPathMaxLengthExcludingExtension;
+ String lastComponent = kurl.lastPathComponent();
+ if (kurl.isLocalFile() || (!isLink && !lastComponent.isEmpty())) {
+ len = std::min<DWORD>(fsPathMaxLengthExcludingExtension, lastComponent.length());
+ StringView(lastComponent).substring(0, len).getCharactersWithUpconvert(fsPathBuffer);
+ } else {
+ len = std::min<DWORD>(fsPathMaxLengthExcludingExtension, url.length());
+ StringView(url).substring(0, len).getCharactersWithUpconvert(fsPathBuffer);
+ }
+ fsPathBuffer[len] = 0;
+ pathRemoveBadFSCharacters(fsPathBuffer, len);
+ }
+
+ if (!extension)
+ return String(static_cast<UChar*>(fsPathBuffer));
+
+ if (!isLink && usedURL) {
+ PathRenameExtension(fsPathBuffer, extension);
+ return String(static_cast<UChar*>(fsPathBuffer));
+ }
+
+ return makeString(static_cast<const UChar*>(fsPathBuffer), extension);
+}
+
+// writeFileToDataObject takes ownership of fileDescriptor and fileContent
+static HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescriptor, HGLOBAL fileContent, HGLOBAL hDropContent)
+{
+ HRESULT hr = S_OK;
+ FORMATETC* fe;
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ if (!fileDescriptor || !fileContent)
+ goto exit;
+
+ // Descriptor
+ fe = fileDescriptorFormat();
+
+ medium.hGlobal = fileDescriptor;
+
+ if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))
+ goto exit;
+
+ // Contents
+ fe = fileContentFormatZero();
+ medium.hGlobal = fileContent;
+ if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))
+ goto exit;
+
+#if USE(CF)
+ // HDROP
+ if (hDropContent) {
+ medium.hGlobal = hDropContent;
+ hr = dataObject->SetData(cfHDropFormat(), &medium, TRUE);
+ }
+#endif
+
+exit:
+ if (FAILED(hr)) {
+ if (fileDescriptor)
+ GlobalFree(fileDescriptor);
+ if (fileContent)
+ GlobalFree(fileContent);
+ if (hDropContent)
+ GlobalFree(hDropContent);
+ }
+ return hr;
+}
+
+void Pasteboard::writeURLToDataObject(const URL& kurl, const String& titleStr)
+{
+ if (!m_writableDataObject)
+ return;
+ WebCore::writeURL(m_writableDataObject.get(), kurl, titleStr, true, true);
+
+ String url = kurl.string();
+ ASSERT(url.containsOnlyASCII()); // URL::string() is URL encoded.
+
+ String fsPath = filesystemPathFromUrlOrTitle(url, titleStr, L".URL", true);
+ String contentString("[InternetShortcut]\r\nURL=" + url + "\r\n");
+ CString content = contentString.latin1();
+
+ if (fsPath.length() <= 0)
+ return;
+
+ HGLOBAL urlFileDescriptor = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
+ if (!urlFileDescriptor)
+ return;
+
+ HGLOBAL urlFileContent = GlobalAlloc(GPTR, content.length());
+ if (!urlFileContent) {
+ GlobalFree(urlFileDescriptor);
+ return;
+ }
+
+ FILEGROUPDESCRIPTOR* fgd = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(urlFileDescriptor));
+ if (!fgd) {
+ GlobalFree(urlFileDescriptor);
+ return;
+ }
+
+ ZeroMemory(fgd, sizeof(FILEGROUPDESCRIPTOR));
+ fgd->cItems = 1;
+ fgd->fgd[0].dwFlags = FD_FILESIZE;
+ fgd->fgd[0].nFileSizeLow = content.length();
+
+ unsigned maxSize = std::min<unsigned>(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
+ StringView(fsPath).substring(0, maxSize).getCharactersWithUpconvert(fgd->fgd[0].cFileName);
+ GlobalUnlock(urlFileDescriptor);
+
+ char* fileContents = static_cast<char*>(GlobalLock(urlFileContent));
+ if (!fileContents) {
+ GlobalFree(urlFileDescriptor);
+ return;
+ }
+
+ CopyMemory(fileContents, content.data(), content.length());
+ GlobalUnlock(urlFileContent);
+
+ writeFileToDataObject(m_writableDataObject.get(), urlFileDescriptor, urlFileContent, 0);
+}
+
+void Pasteboard::write(const PasteboardURL& pasteboardURL)
+{
+ ASSERT(!pasteboardURL.url.isEmpty());
+
+ clear();
+
+ String title(pasteboardURL.title);
+ if (title.isEmpty()) {
+ title = pasteboardURL.url.lastPathComponent();
+ if (title.isEmpty())
+ title = pasteboardURL.url.host();
+ }
+
+ // write to clipboard in format com.apple.safari.bookmarkdata to be able to paste into the bookmarks view with appropriate title
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(pasteboardURL.url, title);
+ if (!::SetClipboardData(BookmarkClipboardFormat, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // write to clipboard in format CF_HTML to be able to paste into contenteditable areas as a link
+ if (::OpenClipboard(m_owner)) {
+ Vector<char> data;
+ markupToCFHTML(urlToMarkup(pasteboardURL.url, title), "", data);
+ HGLOBAL cbData = createGlobalData(data);
+ if (!::SetClipboardData(HTMLClipboardFormat, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ // bare-bones CF_UNICODETEXT support
+ if (::OpenClipboard(m_owner)) {
+ HGLOBAL cbData = createGlobalData(pasteboardURL.url.string());
+ if (!::SetClipboardData(CF_UNICODETEXT, cbData))
+ ::GlobalFree(cbData);
+ ::CloseClipboard();
+ }
+
+ writeURLToDataObject(pasteboardURL.url, pasteboardURL.title);
+}
+
+void Pasteboard::writeImage(Element& element, const URL&, const String&)
+{
+ if (!is<RenderImage>(element.renderer()))
+ return;
+
+ auto& renderer = downcast<RenderImage>(*element.renderer());
+ CachedImage* cachedImage = renderer.cachedImage();
+ if (!cachedImage || cachedImage->errorOccurred())
+ return;
+ Image* image = cachedImage->imageForRenderer(&renderer);
+ ASSERT(image);
+
+ clear();
+
+ HWndDC dc(0);
+ auto compatibleDC = adoptGDIObject(::CreateCompatibleDC(0));
+ auto sourceDC = adoptGDIObject(::CreateCompatibleDC(0));
+ auto resultBitmap = adoptGDIObject(::CreateCompatibleBitmap(dc, image->width(), image->height()));
+ HGDIOBJ oldBitmap = ::SelectObject(compatibleDC.get(), resultBitmap.get());
+
+ BitmapInfo bmInfo = BitmapInfo::create(IntSize(image->size()));
+
+ auto coreBitmap = adoptGDIObject(::CreateDIBSection(dc, &bmInfo, DIB_RGB_COLORS, 0, 0, 0));
+ HGDIOBJ oldSource = ::SelectObject(sourceDC.get(), coreBitmap.get());
+ image->getHBITMAP(coreBitmap.get());
+
+ ::BitBlt(compatibleDC.get(), 0, 0, image->width(), image->height(), sourceDC.get(), 0, 0, SRCCOPY);
+
+ ::SelectObject(sourceDC.get(), oldSource);
+ ::SelectObject(compatibleDC.get(), oldBitmap);
+
+ if (::OpenClipboard(m_owner)) {
+ ::SetClipboardData(CF_BITMAP, resultBitmap.leak());
+ ::CloseClipboard();
+ }
+}
+
+void Pasteboard::writePasteboard(const Pasteboard& sourcePasteboard)
+{
+ notImplemented();
+}
+
+bool Pasteboard::canSmartReplace()
+{
+ return ::IsClipboardFormatAvailable(WebSmartPasteFormat);
+}
+
+void Pasteboard::read(PasteboardPlainText& text)
+{
+ if (::IsClipboardFormatAvailable(CF_UNICODETEXT) && ::OpenClipboard(m_owner)) {
+ if (HANDLE cbData = ::GetClipboardData(CF_UNICODETEXT)) {
+ text.text = static_cast<UChar*>(GlobalLock(cbData));
+ GlobalUnlock(cbData);
+ ::CloseClipboard();
+ return;
+ }
+ ::CloseClipboard();
+ }
+
+ if (::IsClipboardFormatAvailable(CF_TEXT) && ::OpenClipboard(m_owner)) {
+ if (HANDLE cbData = ::GetClipboardData(CF_TEXT)) {
+ // FIXME: This treats the characters as Latin-1, not UTF-8 or even Windows Latin-1. Is that the right encoding?
+ text.text = static_cast<char*>(GlobalLock(cbData));
+ GlobalUnlock(cbData);
+ ::CloseClipboard();
+ return;
+ }
+ ::CloseClipboard();
+ }
+}
+
+PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame& frame, Range& context, bool allowPlainText, bool& chosePlainText)
+{
+ chosePlainText = false;
+
+ if (::IsClipboardFormatAvailable(HTMLClipboardFormat) && ::OpenClipboard(m_owner)) {
+ // get data off of clipboard
+ HANDLE cbData = ::GetClipboardData(HTMLClipboardFormat);
+ if (cbData) {
+ SIZE_T dataSize = ::GlobalSize(cbData);
+ String cfhtml(UTF8Encoding().decode(static_cast<char*>(GlobalLock(cbData)), dataSize));
+ GlobalUnlock(cbData);
+ ::CloseClipboard();
+
+ RefPtr<DocumentFragment> fragment = fragmentFromCFHTML(frame.document(), cfhtml);
+ if (fragment)
+ return fragment.release();
+ } else
+ ::CloseClipboard();
+ }
+
+ if (allowPlainText && ::IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ chosePlainText = true;
+ if (::OpenClipboard(m_owner)) {
+ HANDLE cbData = ::GetClipboardData(CF_UNICODETEXT);
+ if (cbData) {
+ UChar* buffer = static_cast<UChar*>(GlobalLock(cbData));
+ String str(buffer);
+ GlobalUnlock(cbData);
+ ::CloseClipboard();
+ RefPtr<DocumentFragment> fragment = createFragmentFromText(context, str);
+ if (fragment)
+ return fragment.release();
+ } else
+ ::CloseClipboard();
+ }
+ }
+
+ if (allowPlainText && ::IsClipboardFormatAvailable(CF_TEXT)) {
+ chosePlainText = true;
+ if (::OpenClipboard(m_owner)) {
+ HANDLE cbData = ::GetClipboardData(CF_TEXT);
+ if (cbData) {
+ char* buffer = static_cast<char*>(GlobalLock(cbData));
+ String str(buffer);
+ GlobalUnlock(cbData);
+ ::CloseClipboard();
+ RefPtr<DocumentFragment> fragment = createFragmentFromText(context, str);
+ if (fragment)
+ return fragment.release();
+ } else
+ ::CloseClipboard();
+ }
+ }
+
+ return 0;
+}
+
+void Pasteboard::setExternalDataObject(IDataObject *dataObject)
+{
+ m_writableDataObject = 0;
+ m_dataObject = dataObject;
+}
+
+static CachedImage* getCachedImage(Element& element)
+{
+ // Attempt to pull CachedImage from element
+ RenderObject* renderer = element.renderer();
+ if (!is<RenderImage>(renderer))
+ return nullptr;
+
+ auto* image = downcast<RenderImage>(renderer);
+ if (image->cachedImage() && !image->cachedImage()->errorOccurred())
+ return image->cachedImage();
+
+ return nullptr;
+}
+
+static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image)
+{
+ ASSERT_ARG(image, image);
+ ASSERT(image->image()->data());
+
+ HRESULT hr = S_OK;
+ String fsPath;
+ HGLOBAL memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
+ if (!memObj)
+ return 0;
+
+ FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj);
+ if (!fgd) {
+ GlobalFree(memObj);
+ return 0;
+ }
+
+ memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR));
+ fgd->cItems = 1;
+ fgd->fgd[0].dwFlags = FD_FILESIZE;
+ fgd->fgd[0].nFileSizeLow = image->image()->data()->size();
+
+ const String& preferredTitle = title.isEmpty() ? image->response().suggestedFilename() : title;
+ String extension = image->image()->filenameExtension();
+ if (extension.isEmpty()) {
+ // Do not continue processing in the rare and unusual case where a decoded image is not able
+ // to provide a filename extension. Something tricky (like a bait-n-switch) is going on
+ GlobalUnlock(memObj);
+ GlobalFree(memObj);
+ return 0;
+ }
+ extension.insert(".", 0);
+ fsPath = filesystemPathFromUrlOrTitle(url, preferredTitle, extension.charactersWithNullTermination().data(), false);
+
+ if (fsPath.length() <= 0) {
+ GlobalUnlock(memObj);
+ GlobalFree(memObj);
+ return 0;
+ }
+
+ int maxSize = std::min<int>(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
+ StringView(fsPath).substring(0, maxSize).getCharactersWithUpconvert(fgd->fgd[0].cFileName);
+ GlobalUnlock(memObj);
+
+ return memObj;
+}
+
+static HGLOBAL createGlobalImageFileContent(SharedBuffer* data)
+{
+ HGLOBAL memObj = GlobalAlloc(GPTR, data->size());
+ if (!memObj)
+ return 0;
+
+ char* fileContents = (PSTR)GlobalLock(memObj);
+ if (!fileContents) {
+ GlobalFree(memObj);
+ return 0;
+ }
+
+ if (data->data())
+ CopyMemory(fileContents, data->data(), data->size());
+
+ GlobalUnlock(memObj);
+
+ return memObj;
+}
+
+static HGLOBAL createGlobalHDropContent(const URL& url, String& fileName, SharedBuffer* data)
+{
+ if (fileName.isEmpty() || !data)
+ return 0;
+
+ WCHAR filePath[MAX_PATH];
+
+ if (url.isLocalFile()) {
+ String localPath = decodeURLEscapeSequences(url.path());
+ // windows does not enjoy a leading slash on paths
+ if (localPath[0] == '/')
+ localPath = localPath.substring(1);
+ const Vector<UChar>& localPathWide = localPath.charactersWithNullTermination();
+ LPCWSTR localPathStr = localPathWide.data();
+ if (localPathStr && wcslen(localPathStr) + 1 < MAX_PATH)
+ wcscpy_s(filePath, MAX_PATH, localPathStr);
+ else
+ return 0;
+ } else {
+ WCHAR tempPath[MAX_PATH];
+ WCHAR extension[MAX_PATH];
+ if (!::GetTempPath(WTF_ARRAY_LENGTH(tempPath), tempPath))
+ return 0;
+ if (!::PathAppend(tempPath, fileName.charactersWithNullTermination().data()))
+ return 0;
+ LPCWSTR foundExtension = ::PathFindExtension(tempPath);
+ if (foundExtension) {
+ if (wcscpy_s(extension, MAX_PATH, foundExtension))
+ return 0;
+ } else
+ *extension = 0;
+ ::PathRemoveExtension(tempPath);
+ for (int i = 1; i < 10000; i++) {
+ if (swprintf_s(filePath, MAX_PATH, TEXT("%s-%d%s"), tempPath, i, extension) == -1)
+ return 0;
+ if (!::PathFileExists(filePath))
+ break;
+ }
+ HANDLE tempFileHandle = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (tempFileHandle == INVALID_HANDLE_VALUE)
+ return 0;
+
+ // Write the data to this temp file.
+ DWORD written;
+ BOOL tempWriteSucceeded = FALSE;
+ if (data->data())
+ tempWriteSucceeded = WriteFile(tempFileHandle, data->data(), data->size(), &written, 0);
+ CloseHandle(tempFileHandle);
+ if (!tempWriteSucceeded)
+ return 0;
+ }
+
+ SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (wcslen(filePath) + 2));
+ HGLOBAL memObj = GlobalAlloc(GHND | GMEM_SHARE, dropFilesSize);
+ if (!memObj)
+ return 0;
+
+ DROPFILES* dropFiles = (DROPFILES*) GlobalLock(memObj);
+ if (!dropFiles) {
+ GlobalFree(memObj);
+ return 0;
+ }
+
+ dropFiles->pFiles = sizeof(DROPFILES);
+ dropFiles->fWide = TRUE;
+ wcscpy((LPWSTR)(dropFiles + 1), filePath);
+ GlobalUnlock(memObj);
+
+ return memObj;
+}
+
+void Pasteboard::writeImageToDataObject(Element& element, const URL& url)
+{
+ // Shove image data into a DataObject for use as a file
+ CachedImage* cachedImage = getCachedImage(element);
+ if (!cachedImage || !cachedImage->imageForRenderer(element.renderer()) || !cachedImage->isLoaded())
+ return;
+
+ SharedBuffer* imageBuffer = cachedImage->imageForRenderer(element.renderer())->data();
+ if (!imageBuffer || !imageBuffer->size())
+ return;
+
+ HGLOBAL imageFileDescriptor = createGlobalImageFileDescriptor(url.string(), element.fastGetAttribute(HTMLNames::altAttr), cachedImage);
+ if (!imageFileDescriptor)
+ return;
+
+ HGLOBAL imageFileContent = createGlobalImageFileContent(imageBuffer);
+ if (!imageFileContent) {
+ GlobalFree(imageFileDescriptor);
+ return;
+ }
+
+ String fileName = cachedImage->response().suggestedFilename();
+ HGLOBAL hDropContent = createGlobalHDropContent(url, fileName, imageBuffer);
+ if (!hDropContent) {
+ GlobalFree(imageFileDescriptor);
+ GlobalFree(imageFileContent);
+ return;
+ }
+
+ writeFileToDataObject(m_writableDataObject.get(), imageFileDescriptor, imageFileContent, hDropContent);
+}
+
+void Pasteboard::writeURLToWritableDataObject(const URL& url, const String& title)
+{
+ WebCore::writeURL(m_writableDataObject.get(), url, title, true, false);
+}
+
+void Pasteboard::writeMarkup(const String& markup)
+{
+ Vector<char> data;
+ markupToCFHTML(markup, "", data);
+
+ STGMEDIUM medium = {0};
+ medium.tymed = TYMED_HGLOBAL;
+
+ medium.hGlobal = createGlobalData(data);
+ if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
+ GlobalFree(medium.hGlobal);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PathWalker.cpp b/Source/WebCore/platform/win/PathWalker.cpp
new file mode 100644
index 000000000..8ba6ef2b4
--- /dev/null
+++ b/Source/WebCore/platform/win/PathWalker.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 "PathWalker.h"
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+PathWalker::PathWalker(const String& directory, const String& pattern)
+{
+ String path = directory + "\\" + pattern;
+ m_handle = ::FindFirstFileW(path.charactersWithNullTermination().data(), &m_data);
+}
+
+PathWalker::~PathWalker()
+{
+ if (!isValid())
+ return;
+ ::FindClose(m_handle);
+}
+
+bool PathWalker::step()
+{
+ return ::FindNextFileW(m_handle, &m_data);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PathWalker.h b/Source/WebCore/platform/win/PathWalker.h
new file mode 100644
index 000000000..219c83736
--- /dev/null
+++ b/Source/WebCore/platform/win/PathWalker.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``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 ITS 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 <Windows.h>
+#include <wtf/Noncopyable.h>
+
+namespace WTF {
+ class String;
+}
+
+namespace WebCore {
+
+class PathWalker {
+ WTF_MAKE_NONCOPYABLE(PathWalker);
+public:
+ PathWalker(const WTF::String& directory, const WTF::String& pattern);
+ ~PathWalker();
+
+ bool isValid() const { return m_handle != INVALID_HANDLE_VALUE; }
+ const WIN32_FIND_DATAW& data() const { return m_data; }
+
+ bool step();
+
+private:
+ HANDLE m_handle;
+ WIN32_FIND_DATAW m_data;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PlatformMouseEventWin.cpp b/Source/WebCore/platform/win/PlatformMouseEventWin.cpp
new file mode 100644
index 000000000..c52ed3070
--- /dev/null
+++ b/Source/WebCore/platform/win/PlatformMouseEventWin.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2006, 2007, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2008 Torch Mobile Inc.
+ *
+ * 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 "PlatformMouseEvent.h"
+
+#include "GDIUtilities.h"
+#include "HWndDC.h"
+#include <wtf/Assertions.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/MathExtras.h>
+#include <windows.h>
+#include <windowsx.h>
+
+namespace WebCore {
+
+#define HIGH_BIT_MASK_SHORT 0x8000
+
+static IntPoint positionForEvent(HWND hWnd, LPARAM lParam)
+{
+ IntPoint point(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ float inverseScaleFactor = 1.0f / deviceScaleFactorForWindow(hWnd);
+ point.scale(inverseScaleFactor, inverseScaleFactor);
+ return point;
+}
+
+static IntPoint globalPositionForEvent(HWND hWnd, LPARAM lParam)
+{
+ POINT point = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
+ ClientToScreen(hWnd, &point);
+ return point;
+}
+
+static PlatformEvent::Type messageToEventType(UINT message)
+{
+ switch (message) {
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDBLCLK:
+ //MSDN docs say double click is sent on mouse down
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ return PlatformEvent::MousePressed;
+
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ return PlatformEvent::MouseReleased;
+
+ case WM_MOUSELEAVE:
+ case WM_MOUSEMOVE:
+ return PlatformEvent::MouseMoved;
+
+ default:
+ ASSERT_NOT_REACHED();
+ //Move is relatively harmless
+ return PlatformEvent::MouseMoved;
+ }
+}
+
+PlatformMouseEvent::PlatformMouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool didActivateWebView)
+ : PlatformEvent(messageToEventType(message), wParam & MK_SHIFT, wParam & MK_CONTROL, GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT, GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT, currentTime())
+ , m_position(positionForEvent(hWnd, lParam))
+ , m_globalPosition(globalPositionForEvent(hWnd, lParam))
+ , m_clickCount(0)
+ , m_didActivateWebView(didActivateWebView)
+ , m_modifierFlags(wParam)
+{
+ switch (message) {
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ m_button = LeftButton;
+ break;
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDBLCLK:
+ m_button = RightButton;
+ break;
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_MBUTTONDBLCLK:
+ m_button = MiddleButton;
+ break;
+ case WM_MOUSEMOVE:
+ case WM_MOUSELEAVE:
+ if (wParam & MK_LBUTTON)
+ m_button = LeftButton;
+ else if (wParam & MK_MBUTTON)
+ m_button = MiddleButton;
+ else if (wParam & MK_RBUTTON)
+ m_button = RightButton;
+ else
+ m_button = NoButton;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PlatformScreenWin.cpp b/Source/WebCore/platform/win/PlatformScreenWin.cpp
new file mode 100644
index 000000000..95429b889
--- /dev/null
+++ b/Source/WebCore/platform/win/PlatformScreenWin.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
+ *
+ * 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 "PlatformScreen.h"
+
+#include "FloatRect.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "HostWindow.h"
+#include "IntRect.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include <windows.h>
+
+namespace WebCore {
+
+// Returns info for the default monitor if widget is NULL
+static MONITORINFOEX monitorInfoForWidget(Widget* widget)
+{
+ HWND window = widget ? widget->root()->hostWindow()->platformPageClient() : 0;
+ HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
+
+ MONITORINFOEX monitorInfo;
+ monitorInfo.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(monitor, &monitorInfo);
+ return monitorInfo;
+}
+
+static DEVMODE deviceInfoForWidget(Widget* widget)
+{
+ DEVMODE deviceInfo;
+ deviceInfo.dmSize = sizeof(DEVMODE);
+ deviceInfo.dmDriverExtra = 0;
+ MONITORINFOEX monitorInfo = monitorInfoForWidget(widget);
+ EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &deviceInfo);
+
+ return deviceInfo;
+}
+
+int screenDepth(Widget* widget)
+{
+ DEVMODE deviceInfo = deviceInfoForWidget(widget);
+ if (deviceInfo.dmBitsPerPel == 32) {
+ // Some video drivers return 32, but this function is supposed to ignore the alpha
+ // component. See <http://webkit.org/b/42972>.
+ return 24;
+ }
+ return deviceInfo.dmBitsPerPel;
+}
+
+int screenDepthPerComponent(Widget* widget)
+{
+ // FIXME: Assumes RGB -- not sure if this is right.
+ return screenDepth(widget) / 3;
+}
+
+bool screenIsMonochrome(Widget* widget)
+{
+ DEVMODE deviceInfo = deviceInfoForWidget(widget);
+ return deviceInfo.dmColor == DMCOLOR_MONOCHROME;
+}
+
+bool screenHasInvertedColors()
+{
+ return false;
+}
+
+FloatRect screenRect(Widget* widget)
+{
+ MONITORINFOEX monitorInfo = monitorInfoForWidget(widget);
+ return monitorInfo.rcMonitor;
+}
+
+FloatRect screenAvailableRect(Widget* widget)
+{
+ MONITORINFOEX monitorInfo = monitorInfoForWidget(widget);
+ return monitorInfo.rcWork;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/PopupMenuWin.cpp b/Source/WebCore/platform/win/PopupMenuWin.cpp
new file mode 100644
index 000000000..6a0adbe85
--- /dev/null
+++ b/Source/WebCore/platform/win/PopupMenuWin.cpp
@@ -0,0 +1,1422 @@
+/*
+ * Copyright (C) 2006-2008, 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile Inc.
+ * Copyright (C) 2010 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 "PopupMenuWin.h"
+
+#include "BString.h"
+#include "BitmapInfo.h"
+#include "Document.h"
+#include "FloatRect.h"
+#include "Font.h"
+#include "FontSelector.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "HTMLNames.h"
+#include "HWndDC.h"
+#include "HostWindow.h"
+#include "LengthFunctions.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "PlatformMouseEvent.h"
+#include "PlatformScreen.h"
+#include "RenderMenuList.h"
+#include "RenderTheme.h"
+#include "RenderView.h"
+#include "Scrollbar.h"
+#include "ScrollbarTheme.h"
+#include "ScrollbarThemeWin.h"
+#include "TextRun.h"
+#include "WebCoreInstanceHandle.h"
+#include <wtf/WindowsExtras.h>
+
+#include <windows.h>
+#include <windowsx.h>
+
+#define HIGH_BIT_MASK_SHORT 0x8000
+
+using std::min;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+// Default Window animation duration in milliseconds
+static const int defaultAnimationDuration = 200;
+// Maximum height of a popup window
+static const int maxPopupHeight = 320;
+
+const int optionSpacingMiddle = 1;
+const int popupWindowBorderWidth = 1;
+
+static LPCWSTR kPopupWindowClassName = L"PopupWindowClass";
+
+// This is used from within our custom message pump when we want to send a
+// message to the web view and not have our message stolen and sent to
+// the popup window.
+static const UINT WM_HOST_WINDOW_FIRST = WM_USER;
+static const UINT WM_HOST_WINDOW_CHAR = WM_USER + WM_CHAR;
+static const UINT WM_HOST_WINDOW_MOUSEMOVE = WM_USER + WM_MOUSEMOVE;
+
+// FIXME: Remove this as soon as practical.
+static inline bool isASCIIPrintable(unsigned c)
+{
+ return c >= 0x20 && c <= 0x7E;
+}
+
+static void translatePoint(LPARAM& lParam, HWND from, HWND to)
+{
+ POINT pt;
+ pt.x = (short)GET_X_LPARAM(lParam);
+ pt.y = (short)GET_Y_LPARAM(lParam);
+ ::MapWindowPoints(from, to, &pt, 1);
+ lParam = MAKELPARAM(pt.x, pt.y);
+}
+
+static FloatRect monitorFromHwnd(HWND hwnd)
+{
+ HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
+ MONITORINFOEX monitorInfo;
+ monitorInfo.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(monitor, &monitorInfo);
+ return monitorInfo.rcWork;
+}
+
+PopupMenuWin::PopupMenuWin(PopupMenuClient* client)
+ : m_popupClient(client)
+{
+}
+
+PopupMenuWin::~PopupMenuWin()
+{
+ if (m_popup)
+ ::DestroyWindow(m_popup);
+ if (m_scrollbar)
+ m_scrollbar->setParent(0);
+}
+
+void PopupMenuWin::disconnectClient()
+{
+ m_popupClient = 0;
+}
+
+LPCWSTR PopupMenuWin::popupClassName()
+{
+ return kPopupWindowClassName;
+}
+
+void PopupMenuWin::show(const IntRect& r, FrameView* view, int index)
+{
+ calculatePositionAndSize(r, view);
+ if (clientRect().isEmpty())
+ return;
+
+ HWND hostWindow = view->hostWindow()->platformPageClient();
+
+ if (!m_scrollbar && visibleItems() < client()->listSize()) {
+ // We need a scroll bar
+ m_scrollbar = client()->createScrollbar(*this, VerticalScrollbar, SmallScrollbar);
+ m_scrollbar->styleChanged();
+ }
+
+ // We need to reposition the popup window to its final coordinates.
+ // Before calling this, the popup hwnd is currently the size of and at the location of the menu list client so it needs to be updated.
+ ::MoveWindow(m_popup, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), false);
+
+ // Determine whether we should animate our popups
+ // Note: Must use 'BOOL' and 'FALSE' instead of 'bool' and 'false' to avoid stack corruption with SystemParametersInfo
+ BOOL shouldAnimate = FALSE;
+
+ if (client()) {
+ int index = client()->selectedIndex();
+ if (index >= 0)
+ setFocusedIndex(index);
+ }
+
+ if (!::SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &shouldAnimate, 0))
+ shouldAnimate = FALSE;
+
+ if (shouldAnimate) {
+ RECT viewRect = {0};
+ ::GetWindowRect(hostWindow, &viewRect);
+ if (!::IsRectEmpty(&viewRect))
+ ::AnimateWindow(m_popup, defaultAnimationDuration, AW_BLEND);
+ } else
+ ::ShowWindow(m_popup, SW_SHOWNOACTIVATE);
+
+ m_showPopup = true;
+
+ // Protect the popup menu in case its owner is destroyed while we're running the message pump.
+ RefPtr<PopupMenu> protect(this);
+
+ ::SetCapture(hostWindow);
+
+ MSG msg;
+ HWND activeWindow;
+
+ while (::GetMessage(&msg, 0, 0, 0)) {
+ switch (msg.message) {
+ case WM_HOST_WINDOW_MOUSEMOVE:
+ case WM_HOST_WINDOW_CHAR:
+ if (msg.hwnd == m_popup) {
+ // This message should be sent to the host window.
+ msg.hwnd = hostWindow;
+ msg.message -= WM_HOST_WINDOW_FIRST;
+ }
+ break;
+
+ // Steal mouse messages.
+ case WM_NCMOUSEMOVE:
+ case WM_NCLBUTTONDOWN:
+ case WM_NCLBUTTONUP:
+ case WM_NCLBUTTONDBLCLK:
+ case WM_NCRBUTTONDOWN:
+ case WM_NCRBUTTONUP:
+ case WM_NCRBUTTONDBLCLK:
+ case WM_NCMBUTTONDOWN:
+ case WM_NCMBUTTONUP:
+ case WM_NCMBUTTONDBLCLK:
+ case WM_MOUSEWHEEL:
+ msg.hwnd = m_popup;
+ break;
+
+ // These mouse messages use client coordinates so we need to convert them.
+ case WM_MOUSEMOVE:
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_MBUTTONDBLCLK: {
+ // Translate the coordinate.
+ translatePoint(msg.lParam, msg.hwnd, m_popup);
+
+ msg.hwnd = m_popup;
+ break;
+ }
+
+ // Steal all keyboard messages.
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_CHAR:
+ case WM_DEADCHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+ case WM_SYSDEADCHAR:
+ msg.hwnd = m_popup;
+ break;
+ }
+
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+
+ if (!m_popupClient)
+ break;
+
+ if (!m_showPopup)
+ break;
+ activeWindow = ::GetActiveWindow();
+ if (activeWindow != hostWindow && !::IsChild(activeWindow, hostWindow))
+ break;
+ if (::GetCapture() != hostWindow)
+ break;
+ }
+
+ if (::GetCapture() == hostWindow)
+ ::ReleaseCapture();
+
+ // We're done, hide the popup if necessary.
+ hide();
+}
+
+void PopupMenuWin::hide()
+{
+ if (!m_showPopup)
+ return;
+
+ m_showPopup = false;
+
+ ::ShowWindow(m_popup, SW_HIDE);
+
+ if (client())
+ client()->popupDidHide();
+
+ // Post a WM_NULL message to wake up the message pump if necessary.
+ ::PostMessage(m_popup, WM_NULL, 0, 0);
+}
+
+// The screen that the popup is placed on should be whichever one the popup menu button lies on.
+// We fake an hwnd (here we use the popup's hwnd) on top of the button which we can then use to determine the screen.
+// We can then proceed with our final position/size calculations.
+void PopupMenuWin::calculatePositionAndSize(const IntRect& r, FrameView* v)
+{
+ // First get the screen coordinates of the popup menu client.
+ HWND hostWindow = v->hostWindow()->platformPageClient();
+ IntRect absoluteBounds = ((RenderMenuList*)m_popupClient)->absoluteBoundingBoxRect();
+ IntRect absoluteScreenCoords(v->contentsToWindow(absoluteBounds.location()), absoluteBounds.size());
+ POINT absoluteLocation(absoluteScreenCoords.location());
+ if (!::ClientToScreen(hostWindow, &absoluteLocation))
+ return;
+ absoluteScreenCoords.setLocation(absoluteLocation);
+
+ // Now set the popup menu's location temporarily to these coordinates so we can determine which screen the popup should lie on.
+ // We create or move m_popup as necessary.
+ if (!m_popup) {
+ registerClass();
+ DWORD exStyle = WS_EX_LTRREADING;
+ m_popup = ::CreateWindowExW(exStyle, kPopupWindowClassName, L"PopupMenu",
+ WS_POPUP | WS_BORDER,
+ absoluteScreenCoords.x(), absoluteScreenCoords.y(), absoluteScreenCoords.width(), absoluteScreenCoords.height(),
+ hostWindow, 0, WebCore::instanceHandle(), this);
+
+ if (!m_popup)
+ return;
+ } else
+ ::MoveWindow(m_popup, absoluteScreenCoords.x(), absoluteScreenCoords.y(), absoluteScreenCoords.width(), absoluteScreenCoords.height(), false);
+
+ FloatRect screen = monitorFromHwnd(m_popup);
+
+ // Now we determine the actual location and measurements of the popup itself.
+ // r is in absolute document coordinates, but we want to be in screen coordinates.
+
+ // First, move to WebView coordinates
+ IntRect rScreenCoords(v->contentsToWindow(r.location()), r.size());
+ if (Page* page = v->frame().page())
+ rScreenCoords.scale(page->deviceScaleFactor());
+
+ // Then, translate to screen coordinates
+ POINT location(rScreenCoords.location());
+ if (!::ClientToScreen(hostWindow, &location))
+ return;
+
+ rScreenCoords.setLocation(location);
+
+ // First, determine the popup's height
+ int itemCount = client()->listSize();
+ m_itemHeight = client()->menuStyle().font().fontMetrics().height() + optionSpacingMiddle;
+ int naturalHeight = m_itemHeight * itemCount;
+ int popupHeight = std::min(maxPopupHeight, naturalHeight);
+ // The popup should show an integral number of items (i.e. no partial items should be visible)
+ popupHeight -= popupHeight % m_itemHeight;
+
+ // Next determine its width
+ int popupWidth = 0;
+ for (int i = 0; i < itemCount; ++i) {
+ String text = client()->itemText(i);
+ if (text.isEmpty())
+ continue;
+
+ FontCascade itemFont = client()->menuStyle().font();
+ if (client()->itemIsLabel(i)) {
+ auto d = itemFont.fontDescription();
+ d.setWeight(d.bolderWeight());
+ itemFont = FontCascade(d, itemFont.letterSpacing(), itemFont.wordSpacing());
+ itemFont.update(m_popupClient->fontSelector());
+ }
+
+ popupWidth = std::max(popupWidth, static_cast<int>(ceilf(itemFont.width(TextRun(text)))));
+ }
+
+ if (naturalHeight > maxPopupHeight)
+ // We need room for a scrollbar
+ popupWidth += ScrollbarTheme::theme().scrollbarThickness(SmallScrollbar);
+
+ // Add padding to align the popup text with the <select> text
+ popupWidth += std::max<int>(0, client()->clientPaddingRight() - client()->clientInsetRight()) + std::max<int>(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
+
+ // Leave room for the border
+ popupWidth += 2 * popupWindowBorderWidth;
+ popupHeight += 2 * popupWindowBorderWidth;
+
+ // The popup should be at least as wide as the control on the page
+ popupWidth = std::max(rScreenCoords.width() - client()->clientInsetLeft() - client()->clientInsetRight(), popupWidth);
+
+ // Always left-align items in the popup. This matches popup menus on the mac.
+ int popupX = rScreenCoords.x() + client()->clientInsetLeft();
+
+ IntRect popupRect(popupX, rScreenCoords.maxY(), popupWidth, popupHeight);
+
+ // Check that we don't go off the screen vertically
+ if (popupRect.maxY() > screen.height()) {
+ // The popup will go off the screen, so try placing it above the client
+ if (rScreenCoords.y() - popupRect.height() < 0) {
+ // The popup won't fit above, either, so place it whereever's bigger and resize it to fit
+ if ((rScreenCoords.y() + rScreenCoords.height() / 2) < (screen.height() / 2)) {
+ // Below is bigger
+ popupRect.setHeight(screen.height() - popupRect.y());
+ } else {
+ // Above is bigger
+ popupRect.setY(0);
+ popupRect.setHeight(rScreenCoords.y());
+ }
+ } else {
+ // The popup fits above, so reposition it
+ popupRect.setY(rScreenCoords.y() - popupRect.height());
+ }
+ }
+
+ // Check that we don't go off the screen horizontally
+ if (popupRect.x() + popupRect.width() > screen.width() + screen.x())
+ popupRect.setX(screen.x() + screen.width() - popupRect.width());
+ if (popupRect.x() < screen.x())
+ popupRect.setX(screen.x());
+
+ m_windowRect = popupRect;
+ return;
+}
+
+bool PopupMenuWin::setFocusedIndex(int i, bool hotTracking)
+{
+ if (i < 0 || i >= client()->listSize() || i == focusedIndex())
+ return false;
+
+ if (!client()->itemIsEnabled(i))
+ return false;
+
+ invalidateItem(focusedIndex());
+ invalidateItem(i);
+
+ m_focusedIndex = i;
+
+ if (!hotTracking)
+ client()->setTextFromItem(i);
+
+ if (!scrollToRevealSelection())
+ ::UpdateWindow(m_popup);
+
+ return true;
+}
+
+int PopupMenuWin::visibleItems() const
+{
+ return clientRect().height() / m_itemHeight;
+}
+
+int PopupMenuWin::listIndexAtPoint(const IntPoint& point) const
+{
+ return m_scrollOffset + point.y() / m_itemHeight;
+}
+
+int PopupMenuWin::focusedIndex() const
+{
+ return m_focusedIndex;
+}
+
+void PopupMenuWin::focusFirst()
+{
+ if (!client())
+ return;
+
+ int size = client()->listSize();
+
+ for (int i = 0; i < size; ++i)
+ if (client()->itemIsEnabled(i)) {
+ setFocusedIndex(i);
+ break;
+ }
+}
+
+void PopupMenuWin::focusLast()
+{
+ if (!client())
+ return;
+
+ int size = client()->listSize();
+
+ for (int i = size - 1; i > 0; --i)
+ if (client()->itemIsEnabled(i)) {
+ setFocusedIndex(i);
+ break;
+ }
+}
+
+bool PopupMenuWin::down(unsigned lines)
+{
+ if (!client())
+ return false;
+
+ int size = client()->listSize();
+
+ int lastSelectableIndex, selectedListIndex;
+ lastSelectableIndex = selectedListIndex = focusedIndex();
+ for (int i = selectedListIndex + 1; i >= 0 && i < size; ++i)
+ if (client()->itemIsEnabled(i)) {
+ lastSelectableIndex = i;
+ if (i >= selectedListIndex + (int)lines)
+ break;
+ }
+
+ return setFocusedIndex(lastSelectableIndex);
+}
+
+bool PopupMenuWin::up(unsigned lines)
+{
+ if (!client())
+ return false;
+
+ int size = client()->listSize();
+
+ int lastSelectableIndex, selectedListIndex;
+ lastSelectableIndex = selectedListIndex = focusedIndex();
+ for (int i = selectedListIndex - 1; i >= 0 && i < size; --i)
+ if (client()->itemIsEnabled(i)) {
+ lastSelectableIndex = i;
+ if (i <= selectedListIndex - (int)lines)
+ break;
+ }
+
+ return setFocusedIndex(lastSelectableIndex);
+}
+
+void PopupMenuWin::invalidateItem(int index)
+{
+ if (!m_popup)
+ return;
+
+ IntRect damageRect(clientRect());
+ damageRect.setY(m_itemHeight * (index - m_scrollOffset));
+ damageRect.setHeight(m_itemHeight);
+ if (m_scrollbar)
+ damageRect.setWidth(damageRect.width() - m_scrollbar->frameRect().width());
+
+ RECT r = damageRect;
+ ::InvalidateRect(m_popup, &r, TRUE);
+}
+
+IntRect PopupMenuWin::clientRect() const
+{
+ IntRect clientRect = m_windowRect;
+ clientRect.inflate(-popupWindowBorderWidth);
+ clientRect.setLocation(IntPoint(0, 0));
+ return clientRect;
+}
+
+void PopupMenuWin::incrementWheelDelta(int delta)
+{
+ m_wheelDelta += delta;
+}
+
+void PopupMenuWin::reduceWheelDelta(int delta)
+{
+ ASSERT(delta >= 0);
+ ASSERT(delta <= abs(m_wheelDelta));
+
+ if (m_wheelDelta > 0)
+ m_wheelDelta -= delta;
+ else if (m_wheelDelta < 0)
+ m_wheelDelta += delta;
+ else
+ return;
+}
+
+bool PopupMenuWin::scrollToRevealSelection()
+{
+ if (!m_scrollbar)
+ return false;
+
+ int index = focusedIndex();
+
+ if (index < m_scrollOffset) {
+ ScrollableArea::scrollToOffsetWithoutAnimation(VerticalScrollbar, index);
+ return true;
+ }
+
+ if (index >= m_scrollOffset + visibleItems()) {
+ ScrollableArea::scrollToOffsetWithoutAnimation(VerticalScrollbar, index - visibleItems() + 1);
+ return true;
+ }
+
+ return false;
+}
+
+void PopupMenuWin::updateFromElement()
+{
+ if (!m_popup)
+ return;
+
+ m_focusedIndex = client()->selectedIndex();
+
+ ::InvalidateRect(m_popup, 0, TRUE);
+ if (!scrollToRevealSelection())
+ ::UpdateWindow(m_popup);
+}
+
+const int separatorPadding = 4;
+const int separatorHeight = 1;
+void PopupMenuWin::paint(const IntRect& damageRect, HDC hdc)
+{
+ if (!m_popup)
+ return;
+
+ if (!m_DC) {
+ m_DC = adoptGDIObject(::CreateCompatibleDC(HWndDC(m_popup)));
+ if (!m_DC)
+ return;
+ }
+
+ if (m_bmp) {
+ bool keepBitmap = false;
+ BITMAP bitmap;
+ if (::GetObject(m_bmp.get(), sizeof(bitmap), &bitmap))
+ keepBitmap = bitmap.bmWidth == clientRect().width()
+ && bitmap.bmHeight == clientRect().height();
+ if (!keepBitmap)
+ m_bmp.clear();
+ }
+ if (!m_bmp) {
+ BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size());
+ void* pixels = 0;
+ m_bmp = adoptGDIObject(::CreateDIBSection(m_DC.get(), &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0));
+ if (!m_bmp)
+ return;
+
+ ::SelectObject(m_DC.get(), m_bmp.get());
+ }
+
+ GraphicsContext context(m_DC.get());
+
+ int itemCount = client()->listSize();
+
+ // listRect is the damageRect translated into the coordinates of the entire menu list (which is itemCount * m_itemHeight pixels tall)
+ IntRect listRect = damageRect;
+ listRect.move(IntSize(0, m_scrollOffset * m_itemHeight));
+
+ for (int y = listRect.y(); y < listRect.maxY(); y += m_itemHeight) {
+ int index = y / m_itemHeight;
+
+ Color optionBackgroundColor, optionTextColor;
+ PopupMenuStyle itemStyle = client()->itemStyle(index);
+ if (index == focusedIndex()) {
+ optionBackgroundColor = RenderTheme::defaultTheme()->activeListBoxSelectionBackgroundColor();
+ optionTextColor = RenderTheme::defaultTheme()->activeListBoxSelectionForegroundColor();
+ } else {
+ optionBackgroundColor = itemStyle.backgroundColor();
+ optionTextColor = itemStyle.foregroundColor();
+ }
+
+ // itemRect is in client coordinates
+ IntRect itemRect(0, (index - m_scrollOffset) * m_itemHeight, damageRect.width(), m_itemHeight);
+
+ // Draw the background for this menu item
+ if (itemStyle.isVisible())
+ context.fillRect(itemRect, optionBackgroundColor);
+
+ if (client()->itemIsSeparator(index)) {
+ IntRect separatorRect(itemRect.x() + separatorPadding, itemRect.y() + (itemRect.height() - separatorHeight) / 2, itemRect.width() - 2 * separatorPadding, separatorHeight);
+ context.fillRect(separatorRect, optionTextColor);
+ continue;
+ }
+
+ String itemText = client()->itemText(index);
+
+ TextRun textRun(itemText, 0, 0, AllowTrailingExpansion, itemStyle.textDirection(), itemStyle.hasTextDirectionOverride());
+ context.setFillColor(optionTextColor);
+
+ FontCascade itemFont = client()->menuStyle().font();
+ if (client()->itemIsLabel(index)) {
+ auto d = itemFont.fontDescription();
+ d.setWeight(d.bolderWeight());
+ itemFont = FontCascade(d, itemFont.letterSpacing(), itemFont.wordSpacing());
+ itemFont.update(m_popupClient->fontSelector());
+ }
+
+ // Draw the item text
+ if (itemStyle.isVisible()) {
+ int textX = 0;
+ if (client()->menuStyle().textDirection() == LTR) {
+ textX = std::max<int>(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
+ if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent())
+ textX += minimumIntValueForLength(itemStyle.textIndent(), itemRect.width());
+ } else {
+ textX = itemRect.width() - client()->menuStyle().font().width(textRun);
+ textX = std::min<int>(textX, textX - client()->clientPaddingRight() + client()->clientInsetRight());
+ if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent())
+ textX -= minimumIntValueForLength(itemStyle.textIndent(), itemRect.width());
+ }
+ int textY = itemRect.y() + itemFont.fontMetrics().ascent() + (itemRect.height() - itemFont.fontMetrics().height()) / 2;
+ context.drawBidiText(itemFont, textRun, IntPoint(textX, textY));
+ }
+ }
+
+ if (m_scrollbar)
+ m_scrollbar->paint(context, damageRect);
+
+ HWndDC hWndDC;
+ HDC localDC = hdc ? hdc : hWndDC.setHWnd(m_popup);
+
+ ::BitBlt(localDC, damageRect.x(), damageRect.y(), damageRect.width(), damageRect.height(), m_DC.get(), damageRect.x(), damageRect.y(), SRCCOPY);
+}
+
+int PopupMenuWin::scrollSize(ScrollbarOrientation orientation) const
+{
+ return ((orientation == VerticalScrollbar) && m_scrollbar) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
+}
+
+int PopupMenuWin::scrollOffset(ScrollbarOrientation) const
+{
+ return m_scrollOffset;
+}
+
+void PopupMenuWin::setScrollOffset(const IntPoint& offset)
+{
+ scrollTo(offset.y());
+}
+
+void PopupMenuWin::scrollTo(int offset)
+{
+ ASSERT(m_scrollbar);
+
+ if (!m_popup)
+ return;
+
+ if (m_scrollOffset == offset)
+ return;
+
+ int scrolledLines = m_scrollOffset - offset;
+ m_scrollOffset = offset;
+
+ UINT flags = SW_INVALIDATE;
+
+#ifdef CAN_SET_SMOOTH_SCROLLING_DURATION
+ BOOL shouldSmoothScroll = FALSE;
+ ::SystemParametersInfo(SPI_GETLISTBOXSMOOTHSCROLLING, 0, &shouldSmoothScroll, 0);
+ if (shouldSmoothScroll)
+ flags |= MAKEWORD(SW_SMOOTHSCROLL, smoothScrollAnimationDuration);
+#endif
+
+ IntRect listRect = clientRect();
+ if (m_scrollbar)
+ listRect.setWidth(listRect.width() - m_scrollbar->frameRect().width());
+ RECT r = listRect;
+ ::ScrollWindowEx(m_popup, 0, scrolledLines * m_itemHeight, &r, 0, 0, 0, flags);
+ if (m_scrollbar) {
+ r = m_scrollbar->frameRect();
+ ::InvalidateRect(m_popup, &r, TRUE);
+ }
+ ::UpdateWindow(m_popup);
+}
+
+void PopupMenuWin::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
+{
+ IntRect scrollRect = rect;
+ scrollRect.move(scrollbar->x(), scrollbar->y());
+ RECT r = scrollRect;
+ ::InvalidateRect(m_popup, &r, false);
+}
+
+IntSize PopupMenuWin::visibleSize() const
+{
+ return IntSize(m_windowRect.width(), m_scrollbar ? m_scrollbar->visibleSize() : m_windowRect.height());
+}
+
+IntSize PopupMenuWin::contentsSize() const
+{
+ return m_windowRect.size();
+}
+
+IntRect PopupMenuWin::scrollableAreaBoundingBox(bool*) const
+{
+ return m_windowRect;
+}
+
+bool PopupMenuWin::onGetObject(WPARAM wParam, LPARAM lParam, LRESULT& lResult)
+{
+ lResult = 0;
+
+ if (static_cast<LONG>(lParam) != OBJID_CLIENT)
+ return false;
+
+ if (!m_accessiblePopupMenu)
+ m_accessiblePopupMenu = new AccessiblePopupMenu(*this);
+
+ static HMODULE accessibilityLib = nullptr;
+ if (!accessibilityLib) {
+ if (!(accessibilityLib = ::LoadLibraryW(L"oleacc.dll")))
+ return false;
+ }
+
+ static LPFNLRESULTFROMOBJECT procPtr = reinterpret_cast<LPFNLRESULTFROMOBJECT>(::GetProcAddress(accessibilityLib, "LresultFromObject"));
+ if (!procPtr)
+ return false;
+
+ // LresultFromObject returns a reference to the accessible object, stored
+ // in an LRESULT. If this call is not successful, Windows will handle the
+ // request through DefWindowProc.
+ return SUCCEEDED(lResult = procPtr(__uuidof(IAccessible), wParam, m_accessiblePopupMenu.get()));
+}
+
+void PopupMenuWin::registerClass()
+{
+ static bool haveRegisteredWindowClass = false;
+
+ if (haveRegisteredWindowClass)
+ return;
+
+ WNDCLASSEX wcex;
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.hIconSm = 0;
+ wcex.style = CS_DROPSHADOW;
+
+ wcex.lpfnWndProc = PopupMenuWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = sizeof(PopupMenu*); // For the PopupMenu pointer
+ wcex.hInstance = WebCore::instanceHandle();
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = kPopupWindowClassName;
+
+ haveRegisteredWindowClass = true;
+
+ RegisterClassEx(&wcex);
+}
+
+
+LRESULT CALLBACK PopupMenuWin::PopupMenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (PopupMenuWin* popup = static_cast<PopupMenuWin*>(getWindowPointer(hWnd, 0)))
+ return popup->wndProc(hWnd, message, wParam, lParam);
+
+ if (message == WM_CREATE) {
+ LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
+
+ // Associate the PopupMenu with the window.
+ setWindowPointer(hWnd, 0, createStruct->lpCreateParams);
+ return 0;
+ }
+
+ return ::DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+const int smoothScrollAnimationDuration = 5000;
+
+LRESULT PopupMenuWin::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = 0;
+
+ switch (message) {
+ case WM_MOUSEACTIVATE:
+ return MA_NOACTIVATE;
+ case WM_SIZE: {
+ if (!scrollbar())
+ break;
+
+ IntSize size(LOWORD(lParam), HIWORD(lParam));
+ scrollbar()->setFrameRect(IntRect(size.width() - scrollbar()->width(), 0, scrollbar()->width(), size.height()));
+
+ int visibleItems = this->visibleItems();
+ scrollbar()->setEnabled(visibleItems < client()->listSize());
+ scrollbar()->setSteps(1, std::max(1, visibleItems - 1));
+ scrollbar()->setProportion(visibleItems, client()->listSize());
+
+ break;
+ }
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN: {
+ if (!client())
+ break;
+
+ bool altKeyPressed = GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT;
+ bool ctrlKeyPressed = GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT;
+
+ lResult = 0;
+ switch (LOWORD(wParam)) {
+ case VK_F4: {
+ if (!altKeyPressed && !ctrlKeyPressed) {
+ int index = focusedIndex();
+ ASSERT(index >= 0);
+ client()->valueChanged(index);
+ hide();
+ }
+ break;
+ }
+ case VK_DOWN:
+ if (altKeyPressed) {
+ int index = focusedIndex();
+ ASSERT(index >= 0);
+ client()->valueChanged(index);
+ hide();
+ } else
+ down();
+ break;
+ case VK_RIGHT:
+ down();
+ break;
+ case VK_UP:
+ if (altKeyPressed) {
+ int index = focusedIndex();
+ ASSERT(index >= 0);
+ client()->valueChanged(index);
+ hide();
+ } else
+ up();
+ break;
+ case VK_LEFT:
+ up();
+ break;
+ case VK_HOME:
+ focusFirst();
+ break;
+ case VK_END:
+ focusLast();
+ break;
+ case VK_PRIOR:
+ if (focusedIndex() != scrollOffset()) {
+ // Set the selection to the first visible item
+ int firstVisibleItem = scrollOffset();
+ up(focusedIndex() - firstVisibleItem);
+ } else {
+ // The first visible item is selected, so move the selection back one page
+ up(visibleItems());
+ }
+ break;
+ case VK_NEXT: {
+ int lastVisibleItem = scrollOffset() + visibleItems() - 1;
+ if (focusedIndex() != lastVisibleItem) {
+ // Set the selection to the last visible item
+ down(lastVisibleItem - focusedIndex());
+ } else {
+ // The last visible item is selected, so move the selection forward one page
+ down(visibleItems());
+ }
+ break;
+ }
+ case VK_TAB:
+ ::SendMessage(client()->hostWindow()->platformPageClient(), message, wParam, lParam);
+ hide();
+ break;
+ case VK_ESCAPE:
+ hide();
+ break;
+ default:
+ if (isASCIIPrintable(wParam))
+ // Send the keydown to the WebView so it can be used for type-to-select.
+ // Since we know that the virtual key is ASCII printable, it's OK to convert this to
+ // a WM_CHAR message. (We don't want to call TranslateMessage because that will post a
+ // WM_CHAR message that will be stolen and redirected to the popup HWND.
+ ::PostMessage(m_popup, WM_HOST_WINDOW_CHAR, wParam, lParam);
+ else
+ lResult = 1;
+ break;
+ }
+ break;
+ }
+ case WM_CHAR: {
+ if (!client())
+ break;
+
+ lResult = 0;
+ int index;
+ switch (wParam) {
+ case 0x0D: // Enter/Return
+ hide();
+ index = focusedIndex();
+ ASSERT(index >= 0);
+ client()->valueChanged(index);
+ break;
+ case 0x1B: // Escape
+ hide();
+ break;
+ case 0x09: // TAB
+ case 0x08: // Backspace
+ case 0x0A: // Linefeed
+ default: // Character
+ lResult = 1;
+ break;
+ }
+ break;
+ }
+ case WM_MOUSEMOVE: {
+ IntPoint mousePoint(MAKEPOINTS(lParam));
+ if (scrollbar()) {
+ IntRect scrollBarRect = scrollbar()->frameRect();
+ if (scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
+ // Put the point into coordinates relative to the scroll bar
+ mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
+ PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
+ scrollbar()->mouseMoved(event);
+ break;
+ }
+ }
+
+ BOOL shouldHotTrack = FALSE;
+ if (!::SystemParametersInfo(SPI_GETHOTTRACKING, 0, &shouldHotTrack, 0))
+ shouldHotTrack = FALSE;
+
+ RECT bounds;
+ GetClientRect(popupHandle(), &bounds);
+ if (!::PtInRect(&bounds, mousePoint) && !(wParam & MK_LBUTTON) && client()) {
+ // When the mouse is not inside the popup menu and the left button isn't down, just
+ // repost the message to the web view.
+
+ // Translate the coordinate.
+ translatePoint(lParam, m_popup, client()->hostWindow()->platformPageClient());
+
+ ::PostMessage(m_popup, WM_HOST_WINDOW_MOUSEMOVE, wParam, lParam);
+ break;
+ }
+
+ if ((shouldHotTrack || wParam & MK_LBUTTON) && ::PtInRect(&bounds, mousePoint)) {
+ setFocusedIndex(listIndexAtPoint(mousePoint), true);
+ m_hoveredIndex = listIndexAtPoint(mousePoint);
+ }
+
+ break;
+ }
+ case WM_LBUTTONDOWN: {
+ IntPoint mousePoint(MAKEPOINTS(lParam));
+ if (scrollbar()) {
+ IntRect scrollBarRect = scrollbar()->frameRect();
+ if (scrollBarRect.contains(mousePoint)) {
+ // Put the point into coordinates relative to the scroll bar
+ mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
+ PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
+ scrollbar()->mouseDown(event);
+ setScrollbarCapturingMouse(true);
+ break;
+ }
+ }
+
+ // If the mouse is inside the window, update the focused index. Otherwise,
+ // hide the popup.
+ RECT bounds;
+ GetClientRect(m_popup, &bounds);
+ if (::PtInRect(&bounds, mousePoint)) {
+ setFocusedIndex(listIndexAtPoint(mousePoint), true);
+ m_hoveredIndex = listIndexAtPoint(mousePoint);
+ }
+ else
+ hide();
+ break;
+ }
+ case WM_LBUTTONUP: {
+ IntPoint mousePoint(MAKEPOINTS(lParam));
+ if (scrollbar()) {
+ IntRect scrollBarRect = scrollbar()->frameRect();
+ if (scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
+ setScrollbarCapturingMouse(false);
+ // Put the point into coordinates relative to the scroll bar
+ mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
+ PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
+ scrollbar()->mouseUp(event);
+ // FIXME: This is a hack to work around Scrollbar not invalidating correctly when it doesn't have a parent widget
+ RECT r = scrollBarRect;
+ ::InvalidateRect(popupHandle(), &r, TRUE);
+ break;
+ }
+ }
+ // Only hide the popup if the mouse is inside the popup window.
+ RECT bounds;
+ GetClientRect(popupHandle(), &bounds);
+ if (client() && ::PtInRect(&bounds, mousePoint)) {
+ hide();
+ int index = m_hoveredIndex;
+ if (!client()->itemIsEnabled(index))
+ index = client()->selectedIndex();
+ if (index >= 0)
+ client()->valueChanged(index);
+ }
+ break;
+ }
+
+ case WM_MOUSEWHEEL: {
+ if (!scrollbar())
+ break;
+
+ int i = 0;
+ for (incrementWheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)); abs(wheelDelta()) >= WHEEL_DELTA; reduceWheelDelta(WHEEL_DELTA)) {
+ if (wheelDelta() > 0)
+ ++i;
+ else
+ --i;
+ }
+
+ ScrollableArea::scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
+ break;
+ }
+
+ case WM_PAINT: {
+ PAINTSTRUCT paintInfo;
+ ::BeginPaint(popupHandle(), &paintInfo);
+ paint(paintInfo.rcPaint, paintInfo.hdc);
+ ::EndPaint(popupHandle(), &paintInfo);
+ lResult = 0;
+ break;
+ }
+ case WM_PRINTCLIENT:
+ paint(clientRect(), (HDC)wParam);
+ break;
+ case WM_GETOBJECT:
+ onGetObject(wParam, lParam, lResult);
+ break;
+ default:
+ lResult = DefWindowProc(hWnd, message, wParam, lParam);
+ }
+
+ return lResult;
+}
+
+AccessiblePopupMenu::AccessiblePopupMenu(const PopupMenuWin& popupMenu)
+ : m_popupMenu(popupMenu)
+{
+}
+
+AccessiblePopupMenu::~AccessiblePopupMenu()
+{
+}
+
+HRESULT AccessiblePopupMenu::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
+{
+ if (!ppvObject)
+ return E_POINTER;
+ if (IsEqualGUID(riid, __uuidof(IAccessible)))
+ *ppvObject = static_cast<IAccessible*>(this);
+ else if (IsEqualGUID(riid, __uuidof(IDispatch)))
+ *ppvObject = static_cast<IAccessible*>(this);
+ else if (IsEqualGUID(riid, __uuidof(IUnknown)))
+ *ppvObject = static_cast<IAccessible*>(this);
+ else {
+ *ppvObject = nullptr;
+ return E_NOINTERFACE;
+ }
+ AddRef();
+ return S_OK;
+}
+
+ULONG AccessiblePopupMenu::AddRef()
+{
+ return ++m_refCount;
+}
+
+ULONG AccessiblePopupMenu::Release()
+{
+ int refCount = --m_refCount;
+ if (!refCount)
+ delete this;
+ return refCount;
+}
+
+HRESULT AccessiblePopupMenu::GetTypeInfoCount(_Out_ UINT* count)
+{
+ if (!count)
+ return E_POINTER;
+ *count = 0;
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::GetTypeInfo(UINT, LCID, _COM_Outptr_opt_ ITypeInfo** ppTInfo)
+{
+ if (!ppTInfo)
+ return E_POINTER;
+ *ppTInfo = nullptr;
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::GetIDsOfNames(_In_ REFIID, __in_ecount(cNames) LPOLESTR*, UINT cNames, LCID, __out_ecount_full(cNames) DISPID*)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accParent(_COM_Outptr_opt_ IDispatch** parent)
+{
+ if (!parent)
+ return E_POINTER;
+ *parent = nullptr;
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accChildCount(_Out_ long* count)
+{
+ if (!count)
+ return E_POINTER;
+
+ *count = m_popupMenu.visibleItems();
+ return S_OK;
+}
+
+HRESULT AccessiblePopupMenu::get_accChild(VARIANT vChild, _COM_Outptr_opt_ IDispatch** ppChild)
+{
+ if (!ppChild)
+ return E_POINTER;
+
+ *ppChild = nullptr;
+
+ if (vChild.vt != VT_I4)
+ return E_INVALIDARG;
+
+ notImplemented();
+ return S_FALSE;
+}
+
+HRESULT AccessiblePopupMenu::get_accName(VARIANT vChild, __deref_out_opt BSTR* name)
+{
+ return get_accValue(vChild, name);
+}
+
+HRESULT AccessiblePopupMenu::get_accValue(VARIANT vChild, __deref_out_opt BSTR* value)
+{
+ if (!value)
+ return E_POINTER;
+
+ *value = nullptr;
+
+ if (vChild.vt != VT_I4)
+ return E_INVALIDARG;
+
+ int index = vChild.lVal - 1;
+
+ if (index < 0)
+ return E_INVALIDARG;
+
+ BString itemText(m_popupMenu.client()->itemText(index));
+ *value = itemText.release();
+
+ return S_OK;
+}
+
+HRESULT AccessiblePopupMenu::get_accDescription(VARIANT, __deref_out_opt BSTR*)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accRole(VARIANT vChild, _Out_ VARIANT* pvRole)
+{
+ if (!pvRole)
+ return E_POINTER;
+ if (vChild.vt != VT_I4)
+ return E_INVALIDARG;
+
+ // Scrollbar parts are encoded as negative values.
+ if (vChild.lVal < 0) {
+ V_VT(pvRole) = VT_I4;
+ V_I4(pvRole) = ROLE_SYSTEM_SCROLLBAR;
+ } else {
+ V_VT(pvRole) = VT_I4;
+ V_I4(pvRole) = ROLE_SYSTEM_LISTITEM;
+ }
+
+ return S_OK;
+}
+
+HRESULT AccessiblePopupMenu::get_accState(VARIANT vChild, _Out_ VARIANT* pvState)
+{
+ if (!pvState)
+ return E_POINTER;
+
+ if (vChild.vt != VT_I4)
+ return E_INVALIDARG;
+
+ V_VT(pvState) = VT_I4;
+ V_I4(pvState) = 0; // STATE_SYSTEM_NORMAL
+
+ return S_OK;
+}
+
+HRESULT AccessiblePopupMenu::get_accHelp(VARIANT vChild, __deref_out_opt BSTR* helpText)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accKeyboardShortcut(VARIANT vChild, __deref_out_opt BSTR*)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accFocus(_Out_ VARIANT* pvFocusedChild)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accSelection(_Out_ VARIANT* pvSelectedChild)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accDefaultAction(VARIANT vChild, __deref_out_opt BSTR* actionDescription)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::accSelect(long selectionFlags, VARIANT vChild)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::accLocation(_Out_ long* left, _Out_ long* top, _Out_ long* width, _Out_ long* height, VARIANT vChild)
+{
+ if (!left || !top || !width || !height)
+ return E_POINTER;
+
+ if (vChild.vt != VT_I4)
+ return E_INVALIDARG;
+
+ const IntRect& windowRect = m_popupMenu.windowRect();
+
+ // Scrollbar parts are encoded as negative values.
+ if (vChild.lVal < 0) {
+ if (!m_popupMenu.scrollbar())
+ return E_FAIL;
+
+ Scrollbar& scrollbar = *m_popupMenu.scrollbar();
+ WebCore::ScrollbarPart part = static_cast<WebCore::ScrollbarPart>(-vChild.lVal);
+
+ ScrollbarThemeWin& theme = static_cast<ScrollbarThemeWin&>(scrollbar.theme());
+
+ IntRect partRect;
+
+ switch (part) {
+ case BackTrackPart:
+ case BackButtonStartPart:
+ partRect = theme.backButtonRect(scrollbar, WebCore::BackTrackPart);
+ break;
+ case ThumbPart:
+ partRect = theme.thumbRect(scrollbar);
+ break;
+ case ForwardTrackPart:
+ case ForwardButtonEndPart:
+ partRect = theme.forwardButtonRect(scrollbar, WebCore::ForwardTrackPart);
+ break;
+ case ScrollbarBGPart:
+ partRect = theme.trackRect(scrollbar);
+ break;
+ default:
+ return E_FAIL;
+ }
+
+ partRect.move(windowRect.x(), windowRect.y());
+
+ *left = partRect.x();
+ *top = partRect.y();
+ *width = partRect.width();
+ *height = partRect.height();
+
+ return S_OK;
+ }
+
+ int index = vChild.lVal - 1;
+
+ if (index < 0)
+ return E_INVALIDARG;
+
+ *left = windowRect.x();
+ *top = windowRect.y() + (index - m_popupMenu.m_scrollOffset) * m_popupMenu.itemHeight();
+ *width = windowRect.width();
+ *height = m_popupMenu.itemHeight();
+
+ return S_OK;
+}
+
+HRESULT AccessiblePopupMenu::accNavigate(long direction, VARIANT vFromChild, _Out_ VARIANT* pvNavigatedTo)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::accHitTest(long x, long y, _Out_ VARIANT* pvChildAtPoint)
+{
+ if (!pvChildAtPoint)
+ return E_POINTER;
+
+ ::VariantInit(pvChildAtPoint);
+
+ IntRect windowRect = m_popupMenu.windowRect();
+
+ IntPoint pt(x - windowRect.x(), y - windowRect.y());
+
+ IntRect scrollRect;
+
+ if (m_popupMenu.scrollbar())
+ scrollRect = m_popupMenu.scrollbar()->frameRect();
+
+ if (m_popupMenu.scrollbar() && scrollRect.contains(pt)) {
+ Scrollbar& scrollbar = *m_popupMenu.scrollbar();
+
+ pt.move(-scrollRect.x(), -scrollRect.y());
+
+ WebCore::ScrollbarPart part = scrollbar.theme().hitTest(scrollbar, pt);
+
+ V_VT(pvChildAtPoint) = VT_I4;
+ V_I4(pvChildAtPoint) = -part; // Scrollbar parts are encoded as negative, to avoid mixup with item indexes.
+ return S_OK;
+ }
+
+ int index = m_popupMenu.listIndexAtPoint(pt);
+
+ if (index < 0) {
+ V_VT(pvChildAtPoint) = VT_EMPTY;
+ return S_OK;
+ }
+
+ V_VT(pvChildAtPoint) = VT_I4;
+ V_I4(pvChildAtPoint) = index + 1; // CHILDID_SELF is 0, need to add 1.
+
+ return S_OK;
+}
+
+HRESULT AccessiblePopupMenu::accDoDefaultAction(VARIANT vChild)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::put_accName(VARIANT, BSTR)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::put_accValue(VARIANT, BSTR)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+HRESULT AccessiblePopupMenu::get_accHelpTopic(BSTR* helpFile, VARIANT, _Out_ long* topicID)
+{
+ notImplemented();
+ return E_NOTIMPL;
+}
+
+}
diff --git a/Source/WebCore/platform/win/PopupMenuWin.h b/Source/WebCore/platform/win/PopupMenuWin.h
new file mode 100644
index 000000000..2a9b8a5e3
--- /dev/null
+++ b/Source/WebCore/platform/win/PopupMenuWin.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 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 PopupMenuWin_h
+#define PopupMenuWin_h
+
+#include "COMPtr.h"
+#include "IntRect.h"
+#include "PopupMenu.h"
+#include "PopupMenuClient.h"
+#include "ScrollableArea.h"
+#include "Scrollbar.h"
+#include <OleAcc.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/win/GDIObject.h>
+
+namespace WebCore {
+
+class FrameView;
+class Scrollbar;
+class AccessiblePopupMenu;
+
+class PopupMenuWin : public PopupMenu, private ScrollableArea {
+public:
+ PopupMenuWin(PopupMenuClient*);
+ ~PopupMenuWin();
+
+ virtual void show(const IntRect&, FrameView*, int index);
+ virtual void hide();
+ virtual void updateFromElement();
+ virtual void disconnectClient();
+
+ static LPCWSTR popupClassName();
+
+private:
+ PopupMenuClient* client() const { return m_popupClient; }
+
+ Scrollbar* scrollbar() const { return m_scrollbar.get(); }
+
+ bool up(unsigned lines = 1);
+ bool down(unsigned lines = 1);
+
+ int itemHeight() const { return m_itemHeight; }
+ const IntRect& windowRect() const { return m_windowRect; }
+ IntRect clientRect() const;
+
+ int visibleItems() const;
+
+ int listIndexAtPoint(const IntPoint&) const;
+
+ bool setFocusedIndex(int index, bool hotTracking = false);
+ int focusedIndex() const;
+ void focusFirst();
+ void focusLast();
+
+ void paint(const IntRect& damageRect, HDC = 0);
+
+ HWND popupHandle() const { return m_popup; }
+
+ void setWasClicked(bool b = true) { m_wasClicked = b; }
+ bool wasClicked() const { return m_wasClicked; }
+
+ int scrollOffset() const { return m_scrollOffset; }
+
+ bool scrollToRevealSelection();
+
+ void incrementWheelDelta(int delta);
+ void reduceWheelDelta(int delta);
+ int wheelDelta() const { return m_wheelDelta; }
+
+ bool scrollbarCapturingMouse() const { return m_scrollbarCapturingMouse; }
+ void setScrollbarCapturingMouse(bool b) { m_scrollbarCapturingMouse = b; }
+
+ // ScrollableArea
+ virtual int scrollSize(ScrollbarOrientation) const override;
+ virtual int scrollOffset(ScrollbarOrientation) const override;
+ virtual void setScrollOffset(const IntPoint&) override;
+ virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) override;
+ virtual void invalidateScrollCornerRect(const IntRect&) override { }
+ virtual bool isActive() const override { return true; }
+ ScrollableArea* enclosingScrollableArea() const override { return 0; }
+ virtual bool isScrollableOrRubberbandable() override { return true; }
+ virtual bool hasScrollableOrRubberbandableAncestor() override { return true; }
+ virtual bool isScrollCornerVisible() const override { return false; }
+ virtual IntRect scrollCornerRect() const override { return IntRect(); }
+ virtual Scrollbar* verticalScrollbar() const override { return m_scrollbar.get(); }
+ virtual IntSize visibleSize() const override;
+ virtual IntSize contentsSize() const override;
+ virtual IntRect scrollableAreaBoundingBox(bool* = nullptr) const override;
+ virtual bool updatesScrollLayerPositionOnMainThread() const override { return true; }
+ virtual bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override { return false; }
+
+ // NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
+ void scrollTo(int offset);
+
+ void calculatePositionAndSize(const IntRect&, FrameView*);
+ void invalidateItem(int index);
+
+ bool onGetObject(WPARAM wParam, LPARAM lParam, LRESULT& lResult);
+
+ static LRESULT CALLBACK PopupMenuWndProc(HWND, UINT, WPARAM, LPARAM);
+ LRESULT wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+ static void registerClass();
+
+ RefPtr<Scrollbar> m_scrollbar;
+ COMPtr<IAccessible> m_accessiblePopupMenu;
+ GDIObject<HDC> m_DC;
+ GDIObject<HBITMAP> m_bmp;
+ PopupMenuClient* m_popupClient;
+ HWND m_popup { nullptr };
+ IntRect m_windowRect;
+ int m_itemHeight { 0 };
+ int m_scrollOffset { 0 };
+ int m_wheelDelta { 0 };
+ int m_focusedIndex { 0 };
+ int m_hoveredIndex { 0 };
+ bool m_wasClicked { false };
+ bool m_scrollbarCapturingMouse { false };
+ bool m_showPopup { false };
+
+ friend class AccessiblePopupMenu;
+};
+
+class AccessiblePopupMenu : public IAccessible {
+public:
+ AccessiblePopupMenu(const PopupMenuWin&);
+ ~AccessiblePopupMenu();
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID, _COM_Outptr_ void**);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+
+ // IDispatch - Not to be implemented.
+ virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(_Out_ UINT* count);
+ virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT, LCID, _COM_Outptr_opt_ ITypeInfo**);
+ virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(_In_ REFIID, __in_ecount(cNames) LPOLESTR*, UINT cNames, LCID, __out_ecount_full(cNames) DISPID*);
+ virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
+
+ // IAccessible
+ virtual HRESULT STDMETHODCALLTYPE get_accParent(_COM_Outptr_opt_ IDispatch**);
+ virtual HRESULT STDMETHODCALLTYPE get_accChildCount(_Out_ long*);
+ virtual HRESULT STDMETHODCALLTYPE get_accChild(VARIANT vChild, _COM_Outptr_opt_ IDispatch** ppChild);
+ virtual HRESULT STDMETHODCALLTYPE get_accName(VARIANT vChild, __deref_out_opt BSTR*);
+ virtual HRESULT STDMETHODCALLTYPE get_accValue(VARIANT vChild, __deref_out_opt BSTR*);
+ virtual HRESULT STDMETHODCALLTYPE get_accDescription(VARIANT, __deref_out_opt BSTR*);
+ virtual HRESULT STDMETHODCALLTYPE get_accRole(VARIANT vChild, _Out_ VARIANT* pvRole);
+ virtual HRESULT STDMETHODCALLTYPE get_accState(VARIANT vChild, _Out_ VARIANT* pvState);
+ virtual HRESULT STDMETHODCALLTYPE get_accHelp(VARIANT vChild, __deref_out_opt BSTR* helpText);
+ virtual HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(VARIANT vChild, __deref_out_opt BSTR*);
+ virtual HRESULT STDMETHODCALLTYPE get_accFocus(_Out_ VARIANT* pvFocusedChild);
+ virtual HRESULT STDMETHODCALLTYPE get_accSelection(_Out_ VARIANT* pvSelectedChild);
+ virtual HRESULT STDMETHODCALLTYPE get_accDefaultAction(VARIANT vChild, __deref_out_opt BSTR* actionDescription);
+ virtual HRESULT STDMETHODCALLTYPE accSelect(long selectionFlags, VARIANT vChild);
+ virtual HRESULT STDMETHODCALLTYPE accLocation(_Out_ long* left, _Out_ long* top, _Out_ long* width, _Out_ long* height, VARIANT vChild);
+ virtual HRESULT STDMETHODCALLTYPE accNavigate(long direction, VARIANT vFromChild, _Out_ VARIANT* pvNavigatedTo);
+ virtual HRESULT STDMETHODCALLTYPE accHitTest(long x, long y, _Out_ VARIANT* pvChildAtPoint);
+ virtual HRESULT STDMETHODCALLTYPE accDoDefaultAction(VARIANT vChild);
+ virtual HRESULT STDMETHODCALLTYPE put_accName(VARIANT, _In_ BSTR);
+ virtual HRESULT STDMETHODCALLTYPE put_accValue(VARIANT, _In_ BSTR);
+ virtual HRESULT STDMETHODCALLTYPE get_accHelpTopic(BSTR* helpFile, VARIANT, _Out_ long* topicID);
+
+private:
+ int m_refCount { 0 };
+ const PopupMenuWin& m_popupMenu;
+};
+
+} // namespace WebCore
+
+#endif // PopupMenuWin_h
diff --git a/Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp b/Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp
new file mode 100644
index 000000000..48de3877b
--- /dev/null
+++ b/Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008-2009 Torch Mobile Inc.
+ *
+ * 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 "SSLKeyGenerator.h"
+
+#include <wtf/text/Base64.h>
+#include <wtf/text/CString.h>
+
+#include <windows.h>
+#include <wincrypt.h>
+
+namespace WebCore {
+
+void WebCore::getSupportedKeySizes(Vector<String>& v)
+{
+ // FIXME: Strings should be localizable.
+ v.append("High Grade");
+ v.append("Medium Grade");
+}
+
+String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const URL& url)
+{
+ String keyString;
+
+ HCRYPTPROV hContext = 0;
+ HCRYPTKEY hKey = 0;
+ PCERT_PUBLIC_KEY_INFO pPubInfo = 0;
+
+ // Try to delete it if it exists already
+ CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
+
+ do {
+ if (!CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ break;
+
+ DWORD dwPubInfoLength = 0;
+ if (!CryptGenKey(hContext, AT_KEYEXCHANGE, 0, &hKey) || !CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, 0, &dwPubInfoLength))
+ break;
+
+ // Use malloc instead of new, because malloc guarantees to return a pointer aligned for all data types.
+ pPubInfo = reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(fastMalloc(dwPubInfoLength));
+
+ if (!CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pPubInfo, &dwPubInfoLength))
+ break;
+
+ CERT_KEYGEN_REQUEST_INFO requestInfo = { 0 };
+ requestInfo.dwVersion = CERT_KEYGEN_REQUEST_V1;
+ requestInfo.pwszChallengeString = L"";
+ requestInfo.SubjectPublicKeyInfo = *pPubInfo;
+
+ String localChallenge = challenge;
+
+ // Windows API won't write to our buffer, although it's not declared with const.
+ const Vector<UChar>& localChallengeWide = localChallenge.charactersWithNullTermination();
+ requestInfo.pwszChallengeString = const_cast<wchar_t*>(localChallengeWide.data());
+
+ CRYPT_ALGORITHM_IDENTIFIER signAlgo = { 0 };
+ signAlgo.pszObjId = szOID_RSA_SHA1RSA;
+
+ DWORD dwEncodedLength;
+ if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, 0, &dwEncodedLength))
+ break;
+
+ Vector<char> binary(dwEncodedLength);
+ if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, reinterpret_cast<LPBYTE>(binary.data()), &dwEncodedLength))
+ break;
+
+ keyString = base64Encode(binary);
+ } while(0);
+
+ if (pPubInfo)
+ fastFree(pPubInfo);
+
+ if (hKey)
+ CryptDestroyKey(hKey);
+
+ if (hContext)
+ CryptReleaseContext(hContext, 0);
+
+ return keyString;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/ScrollbarThemeWin.cpp b/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
new file mode 100644
index 000000000..5a70de515
--- /dev/null
+++ b/Source/WebCore/platform/win/ScrollbarThemeWin.cpp
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2008, 2013 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 "ScrollbarThemeWin.h"
+
+#include "GDIUtilities.h"
+#include "GraphicsContext.h"
+#include "HWndDC.h"
+#include "LocalWindowsContext.h"
+#include "PlatformMouseEvent.h"
+#include "Scrollbar.h"
+#include "SoftLinking.h"
+#include "SystemInfo.h"
+#include <wtf/win/GDIObject.h>
+
+// Generic state constants
+#define TS_NORMAL 1
+#define TS_HOVER 2
+#define TS_ACTIVE 3
+#define TS_DISABLED 4
+
+#define SP_BUTTON 1
+#define SP_THUMBHOR 2
+#define SP_THUMBVERT 3
+#define SP_TRACKSTARTHOR 4
+#define SP_TRACKENDHOR 5
+#define SP_TRACKSTARTVERT 6
+#define SP_TRACKENDVERT 7
+#define SP_GRIPPERHOR 8
+#define SP_GRIPPERVERT 9
+
+#define TS_UP_BUTTON 0
+#define TS_DOWN_BUTTON 4
+#define TS_LEFT_BUTTON 8
+#define TS_RIGHT_BUTTON 12
+#define TS_UP_BUTTON_HOVER 17
+#define TS_DOWN_BUTTON_HOVER 18
+#define TS_LEFT_BUTTON_HOVER 19
+#define TS_RIGHT_BUTTON_HOVER 20
+
+using namespace std;
+
+namespace WebCore {
+
+static HANDLE scrollbarTheme;
+static bool runningVista;
+
+// FIXME: Refactor the soft-linking code so that it can be shared with RenderThemeWin
+SOFT_LINK_LIBRARY(uxtheme)
+SOFT_LINK(uxtheme, OpenThemeData, HANDLE, WINAPI, (HWND hwnd, LPCWSTR pszClassList), (hwnd, pszClassList))
+SOFT_LINK(uxtheme, CloseThemeData, HRESULT, WINAPI, (HANDLE hTheme), (hTheme))
+SOFT_LINK(uxtheme, DrawThemeBackground, HRESULT, WINAPI, (HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT* pRect, const RECT* pClipRect), (hTheme, hdc, iPartId, iStateId, pRect, pClipRect))
+SOFT_LINK(uxtheme, IsThemeActive, BOOL, WINAPI, (), ())
+SOFT_LINK(uxtheme, IsThemeBackgroundPartiallyTransparent, BOOL, WINAPI, (HANDLE hTheme, int iPartId, int iStateId), (hTheme, iPartId, iStateId))
+
+// Constants used to figure the drag rect outside which we should snap the
+// scrollbar thumb back to its origin. These calculations are based on
+// observing the behavior of the MSVC8 main window scrollbar + some
+// guessing/extrapolation.
+static const int kOffEndMultiplier = 3;
+static const int kOffSideMultiplier = 8;
+
+static void checkAndInitScrollbarTheme()
+{
+ if (uxthemeLibrary() && !scrollbarTheme && IsThemeActive())
+ scrollbarTheme = OpenThemeData(0, L"Scrollbar");
+}
+
+ScrollbarTheme& ScrollbarTheme::nativeTheme()
+{
+ static ScrollbarThemeWin winTheme;
+ return winTheme;
+}
+
+ScrollbarThemeWin::ScrollbarThemeWin()
+{
+ static bool initialized;
+ if (!initialized) {
+ initialized = true;
+ checkAndInitScrollbarTheme();
+ runningVista = (windowsVersion() >= WindowsVista);
+ }
+}
+
+ScrollbarThemeWin::~ScrollbarThemeWin()
+{
+}
+
+static int scrollbarThicknessInPixels()
+{
+ static int thickness = ::GetSystemMetrics(SM_CXVSCROLL);
+ return thickness;
+}
+
+int ScrollbarThemeWin::scrollbarThickness(ScrollbarControlSize)
+{
+ float inverseScaleFactor = 1.0f / deviceScaleFactorForWindow(0);
+ return clampTo<int>(inverseScaleFactor * scrollbarThicknessInPixels());
+}
+
+void ScrollbarThemeWin::themeChanged()
+{
+ if (!scrollbarTheme)
+ return;
+
+ CloseThemeData(scrollbarTheme);
+ scrollbarTheme = 0;
+}
+
+bool ScrollbarThemeWin::invalidateOnMouseEnterExit()
+{
+ return runningVista;
+}
+
+bool ScrollbarThemeWin::hasThumb(Scrollbar& scrollbar)
+{
+ return thumbLength(scrollbar) > 0;
+}
+
+IntRect ScrollbarThemeWin::backButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool)
+{
+ // Windows just has single arrows.
+ if (part == BackButtonEndPart)
+ return IntRect();
+
+ // Our desired rect is essentially 17x17.
+
+ // Our actual rect will shrink to half the available space when
+ // we have < 34 pixels left. This allows the scrollbar
+ // to scale down and function even at tiny sizes.
+ int thickness = scrollbarThickness();
+ if (scrollbar.orientation() == HorizontalScrollbar)
+ return IntRect(scrollbar.x(), scrollbar.y(),
+ scrollbar.width() < 2 * thickness ? scrollbar.width() / 2 : thickness, thickness);
+ return IntRect(scrollbar.x(), scrollbar.y(),
+ thickness, scrollbar.height() < 2 * thickness ? scrollbar.height() / 2 : thickness);
+}
+
+IntRect ScrollbarThemeWin::forwardButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool)
+{
+ // Windows just has single arrows.
+ if (part == ForwardButtonStartPart)
+ return IntRect();
+
+ // Our desired rect is essentially 17x17.
+
+ // Our actual rect will shrink to half the available space when
+ // we have < 34 pixels left. This allows the scrollbar
+ // to scale down and function even at tiny sizes.
+ int thickness = scrollbarThickness();
+ if (scrollbar.orientation() == HorizontalScrollbar) {
+ int w = scrollbar.width() < 2 * thickness ? scrollbar.width() / 2 : thickness;
+ return IntRect(scrollbar.x() + scrollbar.width() - w, scrollbar.y(), w, thickness);
+ }
+
+ int h = scrollbar.height() < 2 * thickness ? scrollbar.height() / 2 : thickness;
+ return IntRect(scrollbar.x(), scrollbar.y() + scrollbar.height() - h, thickness, h);
+}
+
+IntRect ScrollbarThemeWin::trackRect(Scrollbar& scrollbar, bool)
+{
+ int thickness = scrollbarThickness();
+ if (scrollbar.orientation() == HorizontalScrollbar) {
+ if (scrollbar.width() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar.x() + thickness, scrollbar.y(), scrollbar.width() - 2 * thickness, thickness);
+ }
+ if (scrollbar.height() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar.x(), scrollbar.y() + thickness, thickness, scrollbar.height() - 2 * thickness);
+}
+
+ScrollbarButtonPressAction ScrollbarThemeWin::handleMousePressEvent(Scrollbar&, const PlatformMouseEvent& event, ScrollbarPart pressedPart)
+{
+ if (event.button() == RightButton)
+ return ScrollbarButtonPressAction::None;
+
+ switch (pressedPart) {
+ case BackTrackPart:
+ case ForwardTrackPart:
+ if (event.shiftKey() && event.button() == LeftButton)
+ return ScrollbarButtonPressAction::CenterOnThumb;
+ break;
+ case ThumbPart:
+ return ScrollbarButtonPressAction::StartDrag;
+ default:
+ break;
+ }
+
+ return ScrollbarButtonPressAction::Scroll;
+}
+
+bool ScrollbarThemeWin::shouldSnapBackToDragOrigin(Scrollbar& scrollbar, const PlatformMouseEvent& evt)
+{
+ // Find the rect within which we shouldn't snap, by expanding the track rect
+ // in both dimensions.
+ IntRect rect = trackRect(scrollbar);
+ const bool horz = scrollbar.orientation() == HorizontalScrollbar;
+ const int thickness = scrollbarThickness(scrollbar.controlSize());
+ rect.inflateX((horz ? kOffEndMultiplier : kOffSideMultiplier) * thickness);
+ rect.inflateY((horz ? kOffSideMultiplier : kOffEndMultiplier) * thickness);
+
+ // Convert the event to local coordinates.
+ IntPoint mousePosition = scrollbar.convertFromContainingWindow(evt.position());
+ mousePosition.move(scrollbar.x(), scrollbar.y());
+
+ // We should snap iff the event is outside our calculated rect.
+ return !rect.contains(mousePosition);
+}
+
+void ScrollbarThemeWin::paintTrackBackground(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect)
+{
+ // Just assume a forward track part. We only paint the track as a single piece when there is no thumb.
+ if (!hasThumb(scrollbar))
+ paintTrackPiece(context, scrollbar, rect, ForwardTrackPart);
+}
+
+void ScrollbarThemeWin::paintTrackPiece(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart partType)
+{
+ checkAndInitScrollbarTheme();
+
+ bool start = partType == BackTrackPart;
+ int part;
+ if (scrollbar.orientation() == HorizontalScrollbar)
+ part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR;
+ else
+ part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT;
+
+ int state;
+ if (!scrollbar.enabled())
+ state = TS_DISABLED;
+ else if ((scrollbar.hoveredPart() == BackTrackPart && start) ||
+ (scrollbar.hoveredPart() == ForwardTrackPart && !start))
+ state = (scrollbar.pressedPart() == scrollbar.hoveredPart() ? TS_ACTIVE : TS_HOVER);
+ else
+ state = TS_NORMAL;
+
+ bool alphaBlend = false;
+ if (scrollbarTheme)
+ alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state);
+
+ LocalWindowsContext windowsContext(context, rect, alphaBlend);
+ RECT themeRect(rect);
+
+ if (scrollbarTheme)
+ DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), part, state, &themeRect, 0);
+ else {
+ DWORD color3DFace = ::GetSysColor(COLOR_3DFACE);
+ DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR);
+ DWORD colorWindow = ::GetSysColor(COLOR_WINDOW);
+ HDC hdc = windowsContext.hdc();
+ if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar))
+ ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1));
+ else {
+ static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
+ auto patternBitmap = adoptGDIObject(::CreateBitmap(8, 8, 1, 1, patternBits));
+ auto brush = adoptGDIObject(::CreatePatternBrush(patternBitmap.get()));
+ SaveDC(hdc);
+ ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
+ ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE));
+ ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL);
+ ::SelectObject(hdc, brush.get());
+ ::FillRect(hdc, &themeRect, brush.get());
+ ::RestoreDC(hdc, -1);
+ }
+ }
+
+ if (!alphaBlend && !context.isInTransparencyLayer())
+ DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
+}
+
+void ScrollbarThemeWin::paintButton(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart part)
+{
+ checkAndInitScrollbarTheme();
+
+ bool start = (part == BackButtonStartPart);
+ int xpState = 0;
+ int classicState = 0;
+ if (scrollbar.orientation() == HorizontalScrollbar)
+ xpState = start ? TS_LEFT_BUTTON : TS_RIGHT_BUTTON;
+ else
+ xpState = start ? TS_UP_BUTTON : TS_DOWN_BUTTON;
+ classicState = xpState / 4;
+
+ if (!scrollbar.enabled()) {
+ xpState += TS_DISABLED;
+ classicState |= DFCS_INACTIVE;
+ } else if ((scrollbar.hoveredPart() == BackButtonStartPart && start) ||
+ (scrollbar.hoveredPart() == ForwardButtonEndPart && !start)) {
+ if (scrollbar.pressedPart() == scrollbar.hoveredPart()) {
+ xpState += TS_ACTIVE;
+ classicState |= DFCS_PUSHED;
+ classicState |= DFCS_FLAT;
+ } else
+ xpState += TS_HOVER;
+ } else {
+ if (scrollbar.hoveredPart() == NoPart || !runningVista)
+ xpState += TS_NORMAL;
+ else {
+ if (scrollbar.orientation() == HorizontalScrollbar)
+ xpState = start ? TS_LEFT_BUTTON_HOVER : TS_RIGHT_BUTTON_HOVER;
+ else
+ xpState = start ? TS_UP_BUTTON_HOVER : TS_DOWN_BUTTON_HOVER;
+ }
+ }
+
+ bool alphaBlend = false;
+ if (scrollbarTheme)
+ alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BUTTON, xpState);
+
+ LocalWindowsContext windowsContext(context, rect, alphaBlend);
+ RECT themeRect(rect);
+ if (scrollbarTheme)
+ DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), SP_BUTTON, xpState, &themeRect, 0);
+ else
+ ::DrawFrameControl(windowsContext.hdc(), &themeRect, DFC_SCROLL, classicState);
+
+ if (!alphaBlend && !context.isInTransparencyLayer())
+ DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
+}
+
+static IntRect gripperRect(int thickness, const IntRect& thumbRect)
+{
+ // Center in the thumb.
+ int gripperThickness = thickness / 2;
+ return IntRect(thumbRect.x() + (thumbRect.width() - gripperThickness) / 2,
+ thumbRect.y() + (thumbRect.height() - gripperThickness) / 2,
+ gripperThickness, gripperThickness);
+}
+
+static void paintGripper(Scrollbar& scrollbar, HDC hdc, const IntRect& rect)
+{
+ if (!scrollbarTheme)
+ return; // Classic look has no gripper.
+
+ int state;
+ if (!scrollbar.enabled())
+ state = TS_DISABLED;
+ else if (scrollbar.pressedPart() == ThumbPart)
+ state = TS_ACTIVE; // Thumb always stays active once pressed.
+ else if (scrollbar.hoveredPart() == ThumbPart)
+ state = TS_HOVER;
+ else
+ state = TS_NORMAL;
+
+ RECT themeRect(rect);
+ DrawThemeBackground(scrollbarTheme, hdc, scrollbar.orientation() == HorizontalScrollbar ? SP_GRIPPERHOR : SP_GRIPPERVERT, state, &themeRect, 0);
+}
+
+void ScrollbarThemeWin::paintThumb(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect)
+{
+ checkAndInitScrollbarTheme();
+
+ int state;
+ if (!scrollbar.enabled())
+ state = TS_DISABLED;
+ else if (scrollbar.pressedPart() == ThumbPart)
+ state = TS_ACTIVE; // Thumb always stays active once pressed.
+ else if (scrollbar.hoveredPart() == ThumbPart)
+ state = TS_HOVER;
+ else
+ state = TS_NORMAL;
+
+ bool alphaBlend = false;
+ if (scrollbarTheme)
+ alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, scrollbar.orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state);
+ LocalWindowsContext windowsContext(context, rect, alphaBlend);
+ RECT themeRect(rect);
+ if (scrollbarTheme) {
+ DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), scrollbar.orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRect, 0);
+ paintGripper(scrollbar, windowsContext.hdc(), gripperRect(scrollbarThickness(), rect));
+ } else
+ ::DrawEdge(windowsContext.hdc(), &themeRect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
+
+ if (!alphaBlend && !context.isInTransparencyLayer())
+ DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255);
+}
+
+}
+
diff --git a/Source/WebCore/platform/win/ScrollbarThemeWin.h b/Source/WebCore/platform/win/ScrollbarThemeWin.h
new file mode 100644
index 000000000..bd05947dc
--- /dev/null
+++ b/Source/WebCore/platform/win/ScrollbarThemeWin.h
@@ -0,0 +1,62 @@
+/*
+ * 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 ScrollbarThemeWin_h
+#define ScrollbarThemeWin_h
+
+#include "ScrollbarThemeComposite.h"
+
+namespace WebCore {
+
+class ScrollbarThemeWin : public ScrollbarThemeComposite {
+public:
+ ScrollbarThemeWin();
+ virtual ~ScrollbarThemeWin();
+
+ int scrollbarThickness(ScrollbarControlSize = RegularScrollbar) override;
+
+ void themeChanged() override;
+
+ bool invalidateOnMouseEnterExit() override;
+
+ IntRect backButtonRect(Scrollbar&, ScrollbarPart, bool painting = false) override;
+ IntRect forwardButtonRect(Scrollbar&, ScrollbarPart, bool painting = false) override;
+ IntRect trackRect(Scrollbar&, bool painting = false) override;
+
+protected:
+ bool hasButtons(Scrollbar&) override { return true; }
+ bool hasThumb(Scrollbar&) override;
+
+ virtual ScrollbarButtonPressAction handleMousePressEvent(Scrollbar&, const PlatformMouseEvent&, ScrollbarPart) override;
+ bool shouldSnapBackToDragOrigin(Scrollbar&, const PlatformMouseEvent&) override;
+
+ void paintTrackBackground(GraphicsContext&, Scrollbar&, const IntRect&) override;
+ void paintTrackPiece(GraphicsContext&, Scrollbar&, const IntRect&, ScrollbarPart) override;
+ void paintButton(GraphicsContext&, Scrollbar&, const IntRect&, ScrollbarPart) override;
+ void paintThumb(GraphicsContext&, Scrollbar&, const IntRect&) override;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/win/SearchPopupMenuWin.cpp b/Source/WebCore/platform/win/SearchPopupMenuWin.cpp
new file mode 100644
index 000000000..73b684da4
--- /dev/null
+++ b/Source/WebCore/platform/win/SearchPopupMenuWin.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc.
+ * Copyright (C) 2010 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 "SearchPopupMenuWin.h"
+
+#include <wtf/text/AtomicString.h>
+
+#if USE(CF)
+#include <wtf/RetainPtr.h>
+#endif
+
+namespace WebCore {
+
+SearchPopupMenuWin::SearchPopupMenuWin(PopupMenuClient* client)
+ : m_popup(adoptRef(new PopupMenuWin(client)))
+{
+}
+
+PopupMenu* SearchPopupMenuWin::popupMenu()
+{
+ return m_popup.get();
+}
+
+bool SearchPopupMenuWin::enabled()
+{
+#if USE(CF)
+ return true;
+#else
+ return false;
+#endif
+}
+
+#if USE(CF)
+static RetainPtr<CFStringRef> autosaveKey(const String& name)
+{
+ return String("com.apple.WebKit.searchField:" + name).createCFString();
+}
+#endif
+
+void SearchPopupMenuWin::saveRecentSearches(const AtomicString& name, const Vector<RecentSearch>& searchItems)
+{
+ if (name.isEmpty())
+ return;
+
+#if USE(CF)
+ RetainPtr<CFMutableArrayRef> items;
+
+ size_t size = searchItems.size();
+ if (size) {
+ items = adoptCF(CFArrayCreateMutable(0, size, &kCFTypeArrayCallBacks));
+ for (size_t i = 0; i < size; ++i)
+ CFArrayAppendValue(items.get(), searchItems[i].string.createCFString().get());
+ }
+
+ CFPreferencesSetAppValue(autosaveKey(name).get(), items.get(), kCFPreferencesCurrentApplication);
+ CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
+#endif
+}
+
+void SearchPopupMenuWin::loadRecentSearches(const AtomicString& name, Vector<RecentSearch>& searchItems)
+{
+ if (name.isEmpty())
+ return;
+
+#if USE(CF)
+ searchItems.clear();
+ RetainPtr<CFArrayRef> items = adoptCF(reinterpret_cast<CFArrayRef>(CFPreferencesCopyAppValue(autosaveKey(name).get(), kCFPreferencesCurrentApplication)));
+
+ if (!items || CFGetTypeID(items.get()) != CFArrayGetTypeID())
+ return;
+
+ size_t size = CFArrayGetCount(items.get());
+ for (size_t i = 0; i < size; ++i) {
+ CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(items.get(), i);
+ if (CFGetTypeID(item) == CFStringGetTypeID()) {
+ // We are choosing not to use or store search times on Windows at this time, so for now it's OK to use a "distant past" time as a placeholder.
+ searchItems.append({ String{ item }, std::chrono::system_clock::time_point::min() });
+ }
+ }
+#endif
+}
+
+}
diff --git a/Source/WebCore/platform/win/SearchPopupMenuWin.h b/Source/WebCore/platform/win/SearchPopupMenuWin.h
new file mode 100644
index 000000000..e5060b8ab
--- /dev/null
+++ b/Source/WebCore/platform/win/SearchPopupMenuWin.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 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 SearchPopupMenuWin_h
+#define SearchPopupMenuWin_h
+
+#include "PopupMenuWin.h"
+#include "SearchPopupMenu.h"
+
+namespace WebCore {
+
+class SearchPopupMenuWin : public SearchPopupMenu {
+public:
+ SearchPopupMenuWin(PopupMenuClient*);
+
+ virtual PopupMenu* popupMenu();
+ virtual void saveRecentSearches(const AtomicString& name, const Vector<RecentSearch>&);
+ virtual void loadRecentSearches(const AtomicString& name, Vector<RecentSearch>&);
+ virtual bool enabled();
+
+private:
+ RefPtr<PopupMenuWin> m_popup;
+};
+
+}
+
+#endif // SearchPopupMenuWin_h
diff --git a/Source/WebCore/platform/win/SharedBufferWin.cpp b/Source/WebCore/platform/win/SharedBufferWin.cpp
new file mode 100644
index 000000000..2aab3cd42
--- /dev/null
+++ b/Source/WebCore/platform/win/SharedBufferWin.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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 "SharedBuffer.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+RefPtr<SharedBuffer> SharedBuffer::createFromReadingFile(const String& filePath)
+{
+ if (filePath.isEmpty())
+ return 0;
+
+ String nullifiedPath = filePath;
+ HANDLE fileHandle = CreateFileW(nullifiedPath.charactersWithNullTermination().data(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+ if (fileHandle == INVALID_HANDLE_VALUE) {
+ LOG_ERROR("Failed to open file %s to create shared buffer, GetLastError() = %u", filePath.ascii().data(), GetLastError());
+ return 0;
+ }
+
+ RefPtr<SharedBuffer> result;
+ DWORD bytesToRead = GetFileSize(fileHandle, 0);
+ DWORD lastError = GetLastError();
+
+ if (bytesToRead != INVALID_FILE_SIZE || lastError == NO_ERROR) {
+ Vector<char> buffer(bytesToRead);
+ DWORD bytesRead;
+ if (ReadFile(fileHandle, buffer.data(), bytesToRead, &bytesRead, 0) && bytesToRead == bytesRead)
+ result = SharedBuffer::adoptVector(buffer);
+ else
+ LOG_ERROR("Failed to fully read contents of file %s, GetLastError() = %u", filePath.ascii().data(), GetLastError());
+ } else
+ LOG_ERROR("Failed to get filesize of file %s, GetLastError() = %u", filePath.ascii().data(), lastError);
+
+ CloseHandle(fileHandle);
+ return result.release();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/SoftLinking.h b/Source/WebCore/platform/win/SoftLinking.h
new file mode 100644
index 000000000..01fab7947
--- /dev/null
+++ b/Source/WebCore/platform/win/SoftLinking.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2007, 2009-2014 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. AND ITS CONTRIBUTORS ``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 ITS 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 SoftLinking_h
+#define SoftLinking_h
+
+#include <windows.h>
+#include <wtf/Assertions.h>
+
+#pragma mark - Soft-link helper macros
+
+#define SOFT_LINK_LIBRARY_HELPER(lib, suffix) \
+ static HMODULE lib##Library() \
+ { \
+ static HMODULE library = LoadLibraryW(L###lib suffix); \
+ return library; \
+ }
+
+#define SOFT_LINK_GETPROCADDRESS GetProcAddress
+#define SOFT_LINK_LIBRARY(lib) SOFT_LINK_LIBRARY_HELPER(lib, L".dll")
+#define SOFT_LINK_DEBUG_LIBRARY(lib) SOFT_LINK_LIBRARY_HELPER(lib, L"_debug.dll")
+
+#pragma mark - Soft-link macros for use within a single source file
+
+#define SOFT_LINK(library, functionName, resultType, callingConvention, parameterDeclarations, parameterNames) \
+ static resultType callingConvention init##functionName parameterDeclarations; \
+ static resultType (callingConvention*softLink##functionName) parameterDeclarations = init##functionName; \
+ \
+ static resultType callingConvention init##functionName parameterDeclarations \
+ { \
+ softLink##functionName = reinterpret_cast<resultType (callingConvention*) parameterDeclarations>(SOFT_LINK_GETPROCADDRESS(library##Library(), #functionName)); \
+ ASSERT(softLink##functionName); \
+ return softLink##functionName parameterNames; \
+ } \
+ \
+ inline resultType functionName parameterDeclarations \
+ { \
+ return softLink##functionName parameterNames; \
+ }
+
+#define SOFT_LINK_OPTIONAL(library, functionName, resultType, callingConvention, parameterDeclarations) \
+ typedef resultType (callingConvention *functionName##PtrType) parameterDeclarations; \
+ static functionName##PtrType functionName##Ptr() \
+ { \
+ static functionName##PtrType ptr; \
+ static bool initialized; \
+ \
+ if (initialized) \
+ return ptr; \
+ initialized = true; \
+ \
+ ptr = reinterpret_cast<functionName##PtrType>(SOFT_LINK_GETPROCADDRESS(library##Library(), #functionName)); \
+ return ptr; \
+ } \
+
+#define SOFT_LINK_LOADED_LIBRARY(library, functionName, resultType, callingConvention, parameterDeclarations) \
+ typedef resultType (callingConvention *functionName##PtrType) parameterDeclarations; \
+ static functionName##PtrType functionName##Ptr() \
+ { \
+ static functionName##PtrType ptr; \
+ static bool initialized; \
+ \
+ if (initialized) \
+ return ptr; \
+ initialized = true; \
+ \
+ static HINSTANCE libraryInstance = ::GetModuleHandle(L#library); \
+ \
+ ptr = reinterpret_cast<functionName##PtrType>(SOFT_LINK_GETPROCADDRESS(libraryInstance, #functionName)); \
+ return ptr; \
+ } \
+
+/*
+ In order to soft link against functions decorated with __declspec(dllimport), we prepend "softLink_" to the function names.
+ If you use SOFT_LINK_DLL_IMPORT(), you will also need to #define the function name to account for this, e.g.:
+
+ SOFT_LINK_DLL_IMPORT(myLibrary, myFunction, ...)
+ #define myFunction softLink_myFunction
+*/
+#define SOFT_LINK_DLL_IMPORT(library, functionName, resultType, callingConvention, parameterDeclarations, parameterNames) \
+ static resultType callingConvention init##functionName parameterDeclarations; \
+ static resultType(callingConvention*softLink##functionName) parameterDeclarations = init##functionName; \
+ \
+ static resultType callingConvention init##functionName parameterDeclarations \
+ { \
+ softLink##functionName = reinterpret_cast<resultType (callingConvention*)parameterDeclarations>(SOFT_LINK_GETPROCADDRESS(library##Library(), #functionName)); \
+ ASSERT(softLink##functionName); \
+ return softLink##functionName parameterNames; \
+ } \
+ \
+ inline resultType softLink_##functionName parameterDeclarations \
+ { \
+ return softLink##functionName parameterNames; \
+ }
+
+#define SOFT_LINK_DLL_IMPORT_OPTIONAL(library, functionName, resultType, callingConvention, parameterDeclarations) \
+ typedef resultType (callingConvention *functionName##PtrType) parameterDeclarations; \
+ static functionName##PtrType functionName##Ptr() \
+ { \
+ static functionName##PtrType ptr; \
+ static bool initialized; \
+ \
+ if (initialized) \
+ return ptr; \
+ initialized = true; \
+ \
+ ptr = reinterpret_cast<resultType(callingConvention*)parameterDeclarations>(SOFT_LINK_GETPROCADDRESS(library##Library(), #functionName)); \
+ return ptr; \
+ } \
+
+#define SOFT_LINK_DLL_IMPORT_OPTIONAL(library, functionName, resultType, callingConvention, parameterDeclarations) \
+ typedef resultType (callingConvention *functionName##PtrType) parameterDeclarations; \
+ static functionName##PtrType functionName##Ptr() \
+ { \
+ static functionName##PtrType ptr; \
+ static bool initialized; \
+ \
+ if (initialized) \
+ return ptr; \
+ initialized = true; \
+ \
+ ptr = reinterpret_cast<resultType(callingConvention*)parameterDeclarations>(SOFT_LINK_GETPROCADDRESS(library##Library(), #functionName)); \
+ return ptr; \
+ } \
+
+/*
+ Variables exported by a DLL need to be accessed through a function.
+ If you use SOFT_LINK_VARIABLE_DLL_IMPORT(), you will also need to #define the variable name to account for this, e.g.:
+
+ SOFT_LINK_VARIABLE_DLL_IMPORT(myLibrary, myVar, int)
+ #define myVar get_myVar()
+*/
+#define SOFT_LINK_VARIABLE_DLL_IMPORT(library, variableName, variableType) \
+ static variableType get##variableName() \
+ { \
+ static variableType* ptr = reinterpret_cast<variableType*>(SOFT_LINK_GETPROCADDRESS(library##Library(), #variableName)); \
+ ASSERT(ptr); \
+ return *ptr; \
+ } \
+
+/*
+ Note that this will only work for variable types for which a return value of 0 can signal an error.
+ */
+#define SOFT_LINK_VARIABLE_DLL_IMPORT_OPTIONAL(library, variableName, variableType) \
+ static variableType get##variableName() \
+ { \
+ static variableType* ptr = reinterpret_cast<variableType*>(SOFT_LINK_GETPROCADDRESS(library##Library(), #variableName)); \
+ if (!ptr) \
+ return 0; \
+ return *ptr; \
+ } \
+
+#pragma mark - Soft-link macros for sharing across multiple source files
+
+// See Source/WebCore/platform/cf/CoreMediaSoftLink.{cpp,h} for an example implementation.
+
+#define SOFT_LINK_FRAMEWORK_FOR_HEADER(functionNamespace, framework) \
+ namespace functionNamespace { \
+ extern HMODULE framework##Library(bool isOptional = false); \
+ bool is##framework##FrameworkAvailable(); \
+ inline bool is##framework##FrameworkAvailable() { \
+ return framework##Library(true) != nullptr; \
+ } \
+ }
+
+#define SOFT_LINK_FRAMEWORK_HELPER(functionNamespace, framework, suffix) \
+ namespace functionNamespace { \
+ HMODULE framework##Library(bool isOptional = false); \
+ HMODULE framework##Library(bool isOptional) \
+ { \
+ static HMODULE library = LoadLibraryW(L###framework suffix); \
+ ASSERT_WITH_MESSAGE_UNUSED(isOptional, isOptional || library, "Could not load %s", L###framework suffix); \
+ return library; \
+ } \
+ }
+
+#define SOFT_LINK_FRAMEWORK(functionNamespace, framework) SOFT_LINK_FRAMEWORK_HELPER(functionNamespace, framework, L".dll")
+#define SOFT_LINK_DEBUG_FRAMEWORK(functionNamespace, framework) SOFT_LINK_FRAMEWORK_HELPER(functionNamespace, framework, L"_debug.dll")
+
+#ifdef DEBUG_ALL
+#define SOFT_LINK_FRAMEWORK_FOR_SOURCE(functionNamespace, framework) SOFT_LINK_DEBUG_FRAMEWORK(functionNamespace, framework)
+#else
+#define SOFT_LINK_FRAMEWORK_FOR_SOURCE(functionNamespace, framework) SOFT_LINK_FRAMEWORK(functionNamespace, framework)
+#endif
+
+#define SOFT_LINK_CONSTANT_FOR_HEADER(functionNamespace, framework, variableName, variableType) \
+ namespace functionNamespace { \
+ variableType get_##framework##_##variableName(); \
+ }
+
+#define SOFT_LINK_CONSTANT_FOR_SOURCE(functionNamespace, framework, variableName, variableType) \
+ namespace functionNamespace { \
+ static void init##framework##variableName(void* context) { \
+ variableType* ptr = reinterpret_cast<variableType*>(SOFT_LINK_GETPROCADDRESS(framework##Library(), #variableName)); \
+ RELEASE_ASSERT(ptr); \
+ *static_cast<variableType*>(context) = *ptr; \
+ } \
+ variableType get_##framework##_##variableName(); \
+ variableType get_##framework##_##variableName() \
+ { \
+ static variableType constant##framework##variableName; \
+ static dispatch_once_t once; \
+ dispatch_once_f(&once, static_cast<void*>(&constant##framework##variableName), init##framework##variableName); \
+ return constant##framework##variableName; \
+ } \
+ }
+
+#define SOFT_LINK_CONSTANT_MAY_FAIL_FOR_HEADER(functionNamespace, framework, variableName, variableType) \
+ namespace functionNamespace { \
+ bool canLoad_##framework##_##variableName(); \
+ bool init_##framework##_##variableName(); \
+ variableType get_##framework##_##variableName(); \
+ }
+
+#define SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE(functionNamespace, framework, variableName, variableType) \
+ namespace functionNamespace { \
+ static variableType constant##framework##variableName; \
+ bool init_##framework##_##variableName(); \
+ bool init_##framework##_##variableName() \
+ { \
+ variableType* ptr = reinterpret_cast<variableType*>(SOFT_LINK_GETPROCADDRESS(framework##Library(), #variableName)); \
+ if (!ptr) \
+ return false; \
+ constant##framework##variableName = *ptr; \
+ return true; \
+ } \
+ bool canLoad_##framework##_##variableName(); \
+ bool canLoad_##framework##_##variableName() \
+ { \
+ static bool loaded = init_##framework##_##variableName(); \
+ return loaded; \
+ } \
+ variableType get_##framework##_##variableName(); \
+ variableType get_##framework##_##variableName() \
+ { \
+ return constant##framework##variableName; \
+ } \
+ }
+
+#define SOFT_LINK_FUNCTION_FOR_HEADER(functionNamespace, framework, functionName, resultType, parameterDeclarations, parameterNames) \
+ namespace functionNamespace { \
+ extern resultType(__cdecl*softLink##framework##functionName) parameterDeclarations; \
+ inline resultType softLink_##framework##_##functionName parameterDeclarations \
+ { \
+ return softLink##framework##functionName parameterNames; \
+ } \
+ }
+
+#define SOFT_LINK_FUNCTION_FOR_SOURCE(functionNamespace, framework, functionName, resultType, parameterDeclarations, parameterNames) \
+ namespace functionNamespace { \
+ static resultType __cdecl init##framework##functionName parameterDeclarations; \
+ resultType(__cdecl*softLink##framework##functionName) parameterDeclarations = init##framework##functionName; \
+ static resultType __cdecl init##framework##functionName parameterDeclarations \
+ { \
+ softLink##framework##functionName = reinterpret_cast<resultType (__cdecl*)parameterDeclarations>(SOFT_LINK_GETPROCADDRESS(framework##Library(), #functionName)); \
+ RELEASE_ASSERT(softLink##framework##functionName); \
+ return softLink##framework##functionName parameterNames; \
+ } \
+ }
+
+#define SOFT_LINK_FUNCTION_MAY_FAIL_FOR_HEADER(functionNamespace, framework, functionName, resultType, parameterDeclarations, parameterNames) \
+ WTF_EXTERN_C_BEGIN \
+ resultType functionName parameterDeclarations; \
+ WTF_EXTERN_C_END \
+ namespace functionNamespace { \
+ extern resultType (*softLink##framework##functionName) parameterDeclarations; \
+ bool canLoad_##framework##_##functionName(); \
+ bool init_##framework##_##functionName(); \
+ resultType softLink_##framework##_##functionName parameterDeclarations; \
+ }
+
+#define SOFT_LINK_FUNCTION_MAY_FAIL_FOR_SOURCE(functionNamespace, framework, functionName, resultType, parameterDeclarations, parameterNames) \
+ WTF_EXTERN_C_BEGIN \
+ resultType functionName parameterDeclarations; \
+ WTF_EXTERN_C_END \
+ namespace functionNamespace { \
+ resultType (*softLink##framework##functionName) parameterDeclarations = 0; \
+ bool init_##framework##_##functionName(); \
+ bool init_##framework##_##functionName() \
+ { \
+ ASSERT(!softLink##framework##functionName); \
+ softLink##framework##functionName = reinterpret_cast<resultType (__cdecl*)parameterDeclarations>(SOFT_LINK_GETPROCADDRESS(framework##Library(), #functionName)); \
+ return !!softLink##framework##functionName; \
+ } \
+ \
+ bool canLoad_##framework##_##functionName(); \
+ bool canLoad_##framework##_##functionName() \
+ { \
+ static bool loaded = init_##framework##_##functionName(); \
+ return loaded; \
+ } \
+ \
+ resultType softLink_##framework##_##functionName parameterDeclarations; \
+ resultType softLink_##framework##_##functionName parameterDeclarations \
+ { \
+ ASSERT(softLink##framework##functionName); \
+ return softLink##framework##functionName parameterNames; \
+ } \
+ }
+
+#endif // SoftLinking_h
diff --git a/Source/WebCore/platform/win/SoundWin.cpp b/Source/WebCore/platform/win/SoundWin.cpp
new file mode 100644
index 000000000..d138887ca
--- /dev/null
+++ b/Source/WebCore/platform/win/SoundWin.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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 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 "Sound.h"
+
+#include <Windows.h>
+
+namespace WebCore {
+
+void systemBeep() { MessageBeep(static_cast<UINT>(-1)); }
+
+} // namespace WebCore
+
diff --git a/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp b/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp
new file mode 100644
index 000000000..66947fd59
--- /dev/null
+++ b/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 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 "StructuredExceptionHandlerSuppressor.h"
+
+#if defined(_M_IX86)
+extern "C" int __stdcall exceptionHandlerThunk(); // Defined in makesafeseh.asm
+#endif
+
+static bool exceptionShouldTerminateProgram(int code)
+{
+ switch (code) {
+#ifndef NDEBUG
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ case EXCEPTION_FLT_OVERFLOW:
+ case EXCEPTION_FLT_STACK_CHECK:
+ case EXCEPTION_FLT_UNDERFLOW:
+#endif
+ case EXCEPTION_ACCESS_VIOLATION:
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ case EXCEPTION_INT_OVERFLOW:
+ case EXCEPTION_PRIV_INSTRUCTION:
+ case EXCEPTION_IN_PAGE_ERROR:
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ case EXCEPTION_STACK_OVERFLOW:
+ case EXCEPTION_INVALID_DISPOSITION:
+ case EXCEPTION_GUARD_PAGE:
+ case EXCEPTION_INVALID_HANDLE:
+ return true;
+ };
+
+ return false;
+}
+
+extern "C" EXCEPTION_DISPOSITION __stdcall exceptionHandler(struct _EXCEPTION_RECORD* exceptionRecord, void* /*establisherFrame*/, struct _CONTEXT* /*contextRecord*/, void* /*dispatcherContext*/)
+{
+ if (exceptionShouldTerminateProgram(exceptionRecord->ExceptionCode))
+ abort();
+
+ return ExceptionContinueSearch;
+}
+
+namespace WebCore {
+
+#pragma warning(push)
+#pragma warning(disable: 4733) // Disable "not registered as safe handler" warning
+
+StructuredExceptionHandlerSuppressor::StructuredExceptionHandlerSuppressor(ExceptionRegistration& exceptionRegistration)
+{
+#if defined(_M_IX86)
+ // Note: Windows requires that the EXCEPTION_REGISTRATION block (modeled here as our
+ // ExceptionRegistration struct) be stack allocated. Therefore we instantiated it prior
+ // to building this object so that Windows can still find it in stack memory when it
+ // attempts to use the handler.
+
+ // Windows puts an __try/__except block around some calls, such as hooks.
+ // The exception handler then ignores system exceptions like invalid addresses
+ // and null pointers. This class can be used to remove this block and prevent
+ // it from catching the exception. Typically this will cause the exception to crash
+ // which is often desirable to allow crashlogs to be recorded for debugging purposed.
+ // While this class is in scope we replace the Windows exception handler with a custom
+ // handler that indicates exceptions that should not be handled.
+ //
+ // See http://www.microsoft.com/msj/0197/Exception/Exception.aspx,
+ // http://www.microsoft.com/msj/archive/S2CE.aspx
+ // http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf
+ // http://www.codeproject.com/Articles/2126/How-a-C-compiler-implements-exception-handling
+
+ // Windows doesn't like assigning to member variables, so we need to get the value into
+ // a local variable and store it afterwards.
+ void* registration;
+
+ // Note: The FS register on Windows always holds the Thread Information Block.
+ // FS:[0] points to the structured exception handling chain (a chain of
+ // EXCEPTION_REGISTRATION structs).
+ //
+ // struct EXCEPTION_REGISTRATION
+ // {
+ // DWORD next;
+ // DWORD handler;
+ // };
+ //
+ // The first four bytes of FS:[0] point to the 'Next' member in the chain. Grab it so we can restore it later.
+ __asm mov eax, FS:[0]
+ __asm mov [registration], eax
+
+ exceptionRegistration.prev = (ExceptionRegistration*)registration;
+ exceptionRegistration.handler = (void*)exceptionHandlerThunk;
+
+ void* erStructMem = &exceptionRegistration;
+
+ __asm mov eax, erStructMem
+ __asm mov FS:[0], eax
+
+ m_savedExceptionRegistration = registration;
+#else
+ // 64-bit x64 no longer needs dynamic modification of the exception handlers.
+#endif
+}
+
+StructuredExceptionHandlerSuppressor::~StructuredExceptionHandlerSuppressor()
+{
+#if defined(_M_IX86)
+ // Restore the exception handler
+ __asm mov eax, [m_savedExceptionRegistration]
+ __asm mov FS:[0], eax
+#else
+#endif
+}
+
+#pragma warning(pop)
+
+}
diff --git a/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.h b/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.h
new file mode 100644
index 000000000..19168dd5f
--- /dev/null
+++ b/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011, 2013 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. AND ITS CONTRIBUTORS ``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 ITS 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 StructuredExceptionHandlerSuppressor_h
+#define StructuredExceptionHandlerSuppressor_h
+
+#include <excpt.h>
+#include <wtf/Noncopyable.h>
+
+extern "C" EXCEPTION_DISPOSITION __stdcall exceptionHandler(struct _EXCEPTION_RECORD* exceptionRecord, void* establisherFrame, struct _CONTEXT* contextRecord, void* dispatcherContext);
+
+namespace WebCore {
+
+struct ExceptionRegistration {
+ ExceptionRegistration* prev;
+ void* handler;
+};
+
+class StructuredExceptionHandlerSuppressor {
+ WTF_MAKE_NONCOPYABLE(StructuredExceptionHandlerSuppressor);
+public:
+ StructuredExceptionHandlerSuppressor(ExceptionRegistration&);
+ ~StructuredExceptionHandlerSuppressor();
+
+private:
+ void* m_savedExceptionRegistration;
+};
+
+} // namespace WebCore
+
+#endif // StructuredExceptionHandlerSuppressor_h
diff --git a/Source/WebCore/platform/win/TemporaryLinkStubs.cpp b/Source/WebCore/platform/win/TemporaryLinkStubs.cpp
new file mode 100644
index 000000000..65ccaefb1
--- /dev/null
+++ b/Source/WebCore/platform/win/TemporaryLinkStubs.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 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 "NotImplemented.h"
+#include "SSLKeyGenerator.h"
+#if !USE(CFNETWORK)
+#include "CookieStorage.h"
+#endif
+
+namespace WebCore {
+
+// <keygen>
+String signedPublicKeyAndChallengeString(unsigned, const String&, const URL&) { notImplemented(); return String(); }
+void getSupportedKeySizes(Vector<String>&) { notImplemented(); }
+
+#if !USE(CFNETWORK)
+void startObservingCookieChanges(CookieChangeCallbackPtr) { notImplemented(); }
+void stopObservingCookieChanges() { notImplemented(); }
+#endif
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/WCDataObject.cpp b/Source/WebCore/platform/win/WCDataObject.cpp
new file mode 100644
index 000000000..acdcef462
--- /dev/null
+++ b/Source/WebCore/platform/win/WCDataObject.cpp
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2007, 2014-2015 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 "WCDataObject.h"
+
+#include "ClipboardUtilitiesWin.h"
+#include "DragData.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class WCEnumFormatEtc : public IEnumFORMATETC
+{
+public:
+ WCEnumFormatEtc(const Vector<FORMATETC>& formats);
+ WCEnumFormatEtc(const Vector<std::unique_ptr<FORMATETC>>& formats);
+
+ //IUnknown members
+ STDMETHOD(QueryInterface)(_In_ REFIID, _COM_Outptr_ void**);
+ STDMETHOD_(ULONG, AddRef)(void);
+ STDMETHOD_(ULONG, Release)(void);
+
+ //IEnumFORMATETC members
+ STDMETHOD(Next)(ULONG, LPFORMATETC, ULONG*);
+ STDMETHOD(Skip)(ULONG);
+ STDMETHOD(Reset)(void);
+ STDMETHOD(Clone)(IEnumFORMATETC**);
+
+private:
+ Vector<FORMATETC> m_formats;
+ size_t m_current { 0 };
+ long m_ref { 1 };
+};
+
+WCEnumFormatEtc::WCEnumFormatEtc(const Vector<FORMATETC>& formats)
+{
+ for (const auto& format : formats)
+ m_formats.append(format);
+}
+
+WCEnumFormatEtc::WCEnumFormatEtc(const Vector<std::unique_ptr<FORMATETC>>& formats)
+{
+ for (auto& format : formats)
+ m_formats.append(*format);
+}
+
+STDMETHODIMP WCEnumFormatEtc::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
+{
+ if (!ppvObject)
+ return E_POINTER;
+ *ppvObject = nullptr;
+ if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC)) {
+ *ppvObject = this;
+ AddRef();
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP_(ULONG) WCEnumFormatEtc::AddRef()
+{
+ return InterlockedIncrement(&m_ref);
+}
+
+STDMETHODIMP_(ULONG) WCEnumFormatEtc::Release()
+{
+ long c = InterlockedDecrement(&m_ref);
+ if (c == 0)
+ delete this;
+ return c;
+}
+
+STDMETHODIMP WCEnumFormatEtc::Next(ULONG celt, LPFORMATETC lpFormatEtc, ULONG* pceltFetched)
+{
+ if(pceltFetched != 0)
+ *pceltFetched=0;
+
+ ULONG cReturn = celt;
+
+ if (celt <= 0 || !lpFormatEtc || m_current >= m_formats.size())
+ return S_FALSE;
+
+ if (!pceltFetched && celt != 1) // pceltFetched can be 0 only for 1 item request
+ return S_FALSE;
+
+ while (m_current < m_formats.size() && cReturn > 0) {
+ *lpFormatEtc++ = m_formats[m_current++];
+ --cReturn;
+ }
+ if (pceltFetched != 0)
+ *pceltFetched = celt - cReturn;
+
+ return (cReturn == 0) ? S_OK : S_FALSE;
+}
+
+STDMETHODIMP WCEnumFormatEtc::Skip(ULONG celt)
+{
+ if ((m_current + int(celt)) >= m_formats.size())
+ return S_FALSE;
+ m_current += celt;
+ return S_OK;
+}
+
+STDMETHODIMP WCEnumFormatEtc::Reset(void)
+{
+ m_current = 0;
+ return S_OK;
+}
+
+STDMETHODIMP WCEnumFormatEtc::Clone(IEnumFORMATETC** ppCloneEnumFormatEtc)
+{
+ if (!ppCloneEnumFormatEtc)
+ return E_POINTER;
+
+ WCEnumFormatEtc *newEnum = new WCEnumFormatEtc(m_formats);
+ if (!newEnum)
+ return E_OUTOFMEMORY;
+
+ newEnum->AddRef();
+ newEnum->m_current = m_current;
+ *ppCloneEnumFormatEtc = newEnum;
+ return S_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+
+HRESULT WCDataObject::createInstance(WCDataObject** result)
+{
+ if (!result)
+ return E_POINTER;
+ *result = new WCDataObject();
+ return S_OK;
+}
+
+HRESULT WCDataObject::createInstance(WCDataObject** result, const DragDataMap& dataMap)
+{
+ if (!result)
+ return E_POINTER;
+ *result = new WCDataObject;
+
+ for (DragDataMap::const_iterator it = dataMap.begin(); it != dataMap.end(); ++it)
+ setClipboardData(*result, it->key, it->value);
+ return S_OK;
+}
+
+WCDataObject::WCDataObject()
+{
+}
+
+STDMETHODIMP WCDataObject::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
+{
+ if (!ppvObject)
+ return E_POINTER;
+ *ppvObject = nullptr;
+ if (IsEqualIID(riid, IID_IUnknown) ||
+ IsEqualIID(riid, IID_IDataObject)) {
+ *ppvObject=this;
+ }
+ if (*ppvObject) {
+ AddRef();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP_(ULONG) WCDataObject::AddRef( void)
+{
+ return InterlockedIncrement(&m_ref);
+}
+
+STDMETHODIMP_(ULONG) WCDataObject::Release( void)
+{
+ long c = InterlockedDecrement(&m_ref);
+ if (c == 0)
+ delete this;
+ return c;
+}
+
+STDMETHODIMP WCDataObject::GetData(FORMATETC* pformatetcIn, STGMEDIUM* pmedium)
+{
+ if (!pformatetcIn || !pmedium)
+ return E_POINTER;
+ pmedium->hGlobal = nullptr;
+
+ for (size_t i = 0; i < m_formats.size(); ++i) {
+ if (/*pformatetcIn->tymed & m_formats[i]->tymed &&*/ // tymed can be 0 (TYMED_NULL) - but it can have a medium that contains an pUnkForRelease
+ pformatetcIn->lindex == m_formats[i]->lindex
+ && pformatetcIn->dwAspect == m_formats[i]->dwAspect
+ && pformatetcIn->cfFormat == m_formats[i]->cfFormat) {
+ CopyMedium(pmedium, m_medium[i].get(), m_formats[i].get());
+ return S_OK;
+ }
+ }
+ return DV_E_FORMATETC;
+}
+
+STDMETHODIMP WCDataObject::GetDataHere(FORMATETC*, STGMEDIUM*)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP WCDataObject::QueryGetData(FORMATETC* pformatetc)
+{
+ if (!pformatetc)
+ return E_POINTER;
+
+ if (!(DVASPECT_CONTENT & pformatetc->dwAspect))
+ return (DV_E_DVASPECT);
+ HRESULT hr = DV_E_TYMED;
+ for (auto& format : m_formats) {
+ if (pformatetc->tymed & format->tymed) {
+ if (pformatetc->cfFormat == format->cfFormat)
+ return S_OK;
+
+ hr = DV_E_CLIPFORMAT;
+ }
+ else
+ hr = DV_E_TYMED;
+ }
+ return hr;
+}
+
+STDMETHODIMP WCDataObject::GetCanonicalFormatEtc(FORMATETC*, FORMATETC*)
+{
+ return DATA_S_SAMEFORMATETC;
+}
+
+STDMETHODIMP WCDataObject::SetData(FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
+{
+ if (!pformatetc || !pmedium)
+ return E_POINTER;
+
+ auto fetc = std::make_unique<FORMATETC>();
+ std::unique_ptr<STGMEDIUM, StgMediumDeleter> pStgMed(new STGMEDIUM);
+
+ ZeroMemory(fetc.get(), sizeof(FORMATETC));
+ ZeroMemory(pStgMed.get(), sizeof(STGMEDIUM));
+
+ *fetc = *pformatetc;
+ m_formats.append(WTFMove(fetc));
+
+ if(fRelease)
+ *pStgMed = *pmedium;
+ else
+ CopyMedium(pStgMed.get(), pmedium, pformatetc);
+ m_medium.append(WTFMove(pStgMed));
+
+ return S_OK;
+}
+
+void WCDataObject::CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc)
+{
+ switch(pMedSrc->tymed)
+ {
+ case TYMED_HGLOBAL:
+ pMedDest->hGlobal = (HGLOBAL)OleDuplicateData(pMedSrc->hGlobal,pFmtSrc->cfFormat, 0);
+ break;
+ case TYMED_GDI:
+ pMedDest->hBitmap = (HBITMAP)OleDuplicateData(pMedSrc->hBitmap,pFmtSrc->cfFormat, 0);
+ break;
+ case TYMED_MFPICT:
+ pMedDest->hMetaFilePict = (HMETAFILEPICT)OleDuplicateData(pMedSrc->hMetaFilePict,pFmtSrc->cfFormat, 0);
+ break;
+ case TYMED_ENHMF:
+ pMedDest->hEnhMetaFile = (HENHMETAFILE)OleDuplicateData(pMedSrc->hEnhMetaFile,pFmtSrc->cfFormat, 0);
+ break;
+ case TYMED_FILE:
+ pMedSrc->lpszFileName = (LPOLESTR)OleDuplicateData(pMedSrc->lpszFileName,pFmtSrc->cfFormat, 0);
+ break;
+ case TYMED_ISTREAM:
+ pMedDest->pstm = pMedSrc->pstm;
+ pMedSrc->pstm->AddRef();
+ break;
+ case TYMED_ISTORAGE:
+ pMedDest->pstg = pMedSrc->pstg;
+ pMedSrc->pstg->AddRef();
+ break;
+ default:
+ break;
+ }
+ pMedDest->tymed = pMedSrc->tymed;
+ pMedDest->pUnkForRelease = 0;
+ if (pMedSrc->pUnkForRelease) {
+ pMedDest->pUnkForRelease = pMedSrc->pUnkForRelease;
+ pMedSrc->pUnkForRelease->AddRef();
+ }
+}
+STDMETHODIMP WCDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
+{
+ if (!ppenumFormatEtc)
+ return E_POINTER;
+
+ *ppenumFormatEtc=0;
+ switch (dwDirection)
+ {
+ case DATADIR_GET:
+ *ppenumFormatEtc= new WCEnumFormatEtc(m_formats);
+ if (!(*ppenumFormatEtc))
+ return E_OUTOFMEMORY;
+ break;
+
+ case DATADIR_SET:
+ default:
+ return E_NOTIMPL;
+ break;
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP WCDataObject::DAdvise(FORMATETC*, DWORD, IAdviseSink*,DWORD*)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+STDMETHODIMP WCDataObject::DUnadvise(DWORD)
+{
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE WCDataObject::EnumDAdvise(IEnumSTATDATA**)
+{
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+void WCDataObject::clearData(CLIPFORMAT format)
+{
+ size_t ptr = 0;
+ while (ptr < m_formats.size()) {
+ if (m_formats[ptr]->cfFormat == format) {
+ m_formats[ptr] = m_formats.takeLast();
+ m_medium[ptr] = m_medium.takeLast();
+ continue;
+ }
+ ptr++;
+ }
+}
+
+}
diff --git a/Source/WebCore/platform/win/WCDataObject.h b/Source/WebCore/platform/win/WCDataObject.h
new file mode 100644
index 000000000..835ff36df
--- /dev/null
+++ b/Source/WebCore/platform/win/WCDataObject.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007, 2014-2015 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 WCDataObject_h
+#define WCDataObject_h
+
+#include "DragData.h"
+#include <ShlObj.h>
+#include <objidl.h>
+#include <wtf/Forward.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+struct StgMediumDeleter {
+ void operator()(STGMEDIUM* medium)
+ {
+ ::ReleaseStgMedium(medium);
+ }
+};
+
+class WCDataObject : public IDataObject {
+public:
+ void CopyMedium(STGMEDIUM* pMedDest, STGMEDIUM* pMedSrc, FORMATETC* pFmtSrc);
+
+ //IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+
+ //IDataObject
+ virtual HRESULT STDMETHODCALLTYPE GetData(FORMATETC* pformatIn, STGMEDIUM* pmedium);
+ virtual HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC* pformat, STGMEDIUM* pmedium);
+ virtual HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC* pformat);
+ virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC* pformatectIn,FORMATETC* pformatOut);
+ virtual HRESULT STDMETHODCALLTYPE SetData(FORMATETC* pformat, STGMEDIUM*pmedium, BOOL release);
+ virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc);
+ virtual HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC*, DWORD, IAdviseSink*, DWORD*);
+ virtual HRESULT STDMETHODCALLTYPE DUnadvise(DWORD);
+ virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA**);
+
+ void clearData(CLIPFORMAT);
+
+ static HRESULT createInstance(WCDataObject**);
+ static HRESULT createInstance(WCDataObject**, const DragDataMap&);
+private:
+ WCDataObject();
+
+ Vector<std::unique_ptr<FORMATETC>> m_formats;
+ Vector<std::unique_ptr<STGMEDIUM, StgMediumDeleter>> m_medium;
+ long m_ref { 1 };
+};
+
+}
+
+#endif //!WCDataObject_h
diff --git a/Source/WebCore/platform/win/WebCoreBundleWin.cpp b/Source/WebCore/platform/win/WebCoreBundleWin.cpp
new file mode 100644
index 000000000..3b7c8e1a2
--- /dev/null
+++ b/Source/WebCore/platform/win/WebCoreBundleWin.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011, 2013 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. AND ITS CONTRIBUTORS ``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 ITS 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 "WebCoreBundleWin.h"
+
+#if USE(CF)
+
+#include "WebCoreInstanceHandle.h"
+#include <CoreFoundation/CFBundle.h>
+#include <windows.h>
+#include <wtf/RetainPtr.h>
+
+namespace WebCore {
+
+static CFBundleRef createWebKitBundle()
+{
+ if (CFBundleRef existingBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit"))) {
+ CFRetain(existingBundle);
+ return existingBundle;
+ }
+
+ wchar_t dllPathBuffer[MAX_PATH];
+ DWORD length = ::GetModuleFileNameW(WebCore::instanceHandle(), dllPathBuffer, WTF_ARRAY_LENGTH(dllPathBuffer));
+ ASSERT(length);
+ ASSERT(length < WTF_ARRAY_LENGTH(dllPathBuffer));
+
+ RetainPtr<CFStringRef> dllPath = adoptCF(CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar*>(dllPathBuffer), length, kCFAllocatorNull));
+ RetainPtr<CFURLRef> dllURL = adoptCF(CFURLCreateWithFileSystemPath(0, dllPath.get(), kCFURLWindowsPathStyle, false));
+ RetainPtr<CFURLRef> dllDirectoryURL = adoptCF(CFURLCreateCopyDeletingLastPathComponent(0, dllURL.get()));
+ RetainPtr<CFURLRef> resourcesDirectoryURL = adoptCF(CFURLCreateCopyAppendingPathComponent(0, dllDirectoryURL.get(), CFSTR("WebKit.resources"), true));
+
+ return CFBundleCreate(0, resourcesDirectoryURL.get());
+}
+
+CFBundleRef webKitBundle()
+{
+ static CFBundleRef bundle = createWebKitBundle();
+ ASSERT(bundle);
+ return bundle;
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/win/WebCoreBundleWin.h b/Source/WebCore/platform/win/WebCoreBundleWin.h
new file mode 100644
index 000000000..af77249fb
--- /dev/null
+++ b/Source/WebCore/platform/win/WebCoreBundleWin.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 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. AND ITS CONTRIBUTORS ``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 ITS 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 WebCoreBundleWin_h
+#define WebCoreBundleWin_h
+
+#if USE(CF)
+
+typedef struct __CFBundle* CFBundleRef;
+
+namespace WebCore {
+
+CFBundleRef webKitBundle();
+
+}
+
+#endif
+
+#endif // WebCoreBundleWin_h
diff --git a/Source/WebCore/platform/win/WebCoreTextRenderer.cpp b/Source/WebCore/platform/win/WebCoreTextRenderer.cpp
new file mode 100644
index 000000000..76f90c110
--- /dev/null
+++ b/Source/WebCore/platform/win/WebCoreTextRenderer.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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 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 "WebCoreTextRenderer.h"
+
+#include "FontCascade.h"
+#include "FontDescription.h"
+#include "GraphicsContext.h"
+#include "StringTruncator.h"
+#include "TextRun.h"
+
+namespace WebCore {
+
+static bool shouldUseFontSmoothing = true;
+
+static bool isOneLeftToRightRun(const TextRun& run)
+{
+ for (int i = 0; i < run.length(); i++) {
+ UCharDirection direction = u_charDirection(run[i]);
+ if (direction == U_RIGHT_TO_LEFT || direction > U_OTHER_NEUTRAL)
+ return false;
+ }
+ return true;
+}
+
+static void doDrawTextAtPoint(GraphicsContext& context, const String& text, const IntPoint& point, const FontCascade& font, const Color& color, int underlinedIndex)
+{
+ TextRun run(text);
+
+ context.setFillColor(color);
+ if (isOneLeftToRightRun(run))
+ font.drawText(context, run, point);
+ else
+ context.drawBidiText(font, run, point);
+
+ if (underlinedIndex >= 0) {
+ ASSERT_WITH_SECURITY_IMPLICATION(underlinedIndex < static_cast<int>(text.length()));
+
+ int beforeWidth;
+ if (underlinedIndex > 0) {
+ TextRun beforeRun(StringView(text).substring(0, underlinedIndex));
+ beforeWidth = font.width(beforeRun);
+ } else
+ beforeWidth = 0;
+
+ TextRun underlinedRun(StringView(text).substring(underlinedIndex, 1));
+ int underlinedWidth = font.width(underlinedRun);
+
+ IntPoint underlinePoint(point);
+ underlinePoint.move(beforeWidth, 1);
+
+ context.setStrokeColor(color);
+ context.drawLineForText(underlinePoint, underlinedWidth, false);
+ }
+}
+
+void WebCoreDrawDoubledTextAtPoint(GraphicsContext& context, const String& text, const IntPoint& point, const FontCascade& font, const Color& topColor, const Color& bottomColor, int underlinedIndex)
+{
+ context.save();
+
+ IntPoint textPos = point;
+
+ doDrawTextAtPoint(context, text, textPos, font, bottomColor, underlinedIndex);
+ textPos.move(0, -1);
+ doDrawTextAtPoint(context, text, textPos, font, topColor, underlinedIndex);
+
+ context.restore();
+}
+
+float WebCoreTextFloatWidth(const String& text, const FontCascade& font)
+{
+ return StringTruncator::width(text, font);
+}
+
+void WebCoreSetShouldUseFontSmoothing(bool smooth)
+{
+ shouldUseFontSmoothing = smooth;
+}
+
+bool WebCoreShouldUseFontSmoothing()
+{
+ return shouldUseFontSmoothing;
+}
+
+void WebCoreSetAlwaysUsesComplexTextCodePath(bool complex)
+{
+ FontCascade::setCodePath(complex ? FontCascade::Complex : FontCascade::Auto);
+}
+
+bool WebCoreAlwaysUsesComplexTextCodePath()
+{
+ return FontCascade::codePath() == FontCascade::Complex;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/WebCoreTextRenderer.h b/Source/WebCore/platform/win/WebCoreTextRenderer.h
new file mode 100644
index 000000000..b843f760b
--- /dev/null
+++ b/Source/WebCore/platform/win/WebCoreTextRenderer.h
@@ -0,0 +1,49 @@
+/*
+ * 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 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 WebCoreTextRenderer_h
+#define WebCoreTextRenderer_h
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+ class Color;
+ class FontCascade;
+ class GraphicsContext;
+ class IntPoint;
+
+ void WebCoreDrawDoubledTextAtPoint(GraphicsContext&, const String&, const IntPoint&, const FontCascade&, const Color& topColor, const Color& bottomColor, int underlinedIndex = -1);
+ float WebCoreTextFloatWidth(const String&, const FontCascade&);
+
+ void WebCoreSetShouldUseFontSmoothing(bool);
+ bool WebCoreShouldUseFontSmoothing();
+
+ void WebCoreSetAlwaysUsesComplexTextCodePath(bool);
+ bool WebCoreAlwaysUsesComplexTextCodePath();
+
+} // namespace WebCore
+
+#endif // WebCoreTextRenderer_h
diff --git a/Source/WebCore/platform/win/WheelEventWin.cpp b/Source/WebCore/platform/win/WheelEventWin.cpp
new file mode 100644
index 000000000..9ef248bc7
--- /dev/null
+++ b/Source/WebCore/platform/win/WheelEventWin.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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 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 "PlatformWheelEvent.h"
+
+#include "FloatPoint.h"
+#include "FloatSize.h"
+#include "GDIUtilities.h"
+#include "HWndDC.h"
+#include <windows.h>
+#include <windowsx.h>
+
+namespace WebCore {
+
+#define HIGH_BIT_MASK_SHORT 0x8000
+#define SPI_GETWHEELSCROLLCHARS 0x006C
+
+static IntPoint positionForEvent(HWND hWnd, LPARAM lParam)
+{
+ POINT point = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
+ ScreenToClient(hWnd, &point);
+ IntPoint logicalPoint(point);
+ float inverseScaleFactor = 1.0f / deviceScaleFactorForWindow(hWnd);
+ logicalPoint.scale(inverseScaleFactor, inverseScaleFactor);
+ return logicalPoint;
+}
+
+static IntPoint globalPositionForEvent(HWND hWnd, LPARAM lParam)
+{
+ IntPoint logicalPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ float inverseScaleFactor = 1.0f / deviceScaleFactorForWindow(hWnd);
+ logicalPoint.scale(inverseScaleFactor, inverseScaleFactor);
+ return logicalPoint;
+}
+
+static int horizontalScrollChars()
+{
+ static ULONG scrollChars;
+ if (!scrollChars && !SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0))
+ scrollChars = 1;
+ return scrollChars;
+}
+
+static int verticalScrollLines()
+{
+ static ULONG scrollLines;
+ if (!scrollLines && !SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0))
+ scrollLines = 3;
+ return scrollLines;
+}
+
+PlatformWheelEvent::PlatformWheelEvent(HWND hWnd, const FloatSize& delta, const FloatPoint& location)
+ : PlatformEvent(PlatformEvent::Wheel, false, false, false, false, ::GetTickCount() * 0.001)
+ , m_directionInvertedFromDevice(false)
+{
+ m_deltaX = delta.width();
+ m_deltaY = delta.height();
+
+ m_wheelTicksX = m_deltaX;
+ m_wheelTicksY = m_deltaY;
+
+ // Global Position is just x, y location of event
+ POINT point = {location.x(), location.y()};
+ float inverseScaleFactor = 1.0f / deviceScaleFactorForWindow(hWnd);
+ m_globalPosition = point;
+ m_globalPosition.scale(inverseScaleFactor, inverseScaleFactor);
+
+ // Position needs to be translated to our client
+ ScreenToClient(hWnd, &point);
+ m_position = point;
+ m_position.scale(inverseScaleFactor, inverseScaleFactor);
+}
+
+PlatformWheelEvent::PlatformWheelEvent(HWND hWnd, WPARAM wParam, LPARAM lParam, bool isMouseHWheel)
+ : PlatformEvent(PlatformEvent::Wheel, wParam & MK_SHIFT, wParam & MK_CONTROL, GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT, GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT, ::GetTickCount() * 0.001)
+ , m_position(positionForEvent(hWnd, lParam))
+ , m_globalPosition(globalPositionForEvent(hWnd, lParam))
+ , m_directionInvertedFromDevice(false)
+{
+ float scaleFactor = deviceScaleFactorForWindow(hWnd);
+
+ // How many pixels should we scroll per line? Gecko uses the height of the
+ // current line, which means scroll distance changes as you go through the
+ // page or go to different pages. IE 7 is ~50 px/line, although the value
+ // seems to vary slightly by page and zoom level. Since IE 7 has a
+ // smoothing algorithm on scrolling, it can get away with slightly larger
+ // scroll values without feeling jerky. Here we use 100 px per three lines
+ // (the default scroll amount on Windows is three lines per wheel tick).
+ static const float cScrollbarPixelsPerLine = scaleFactor * 100.0f / 3.0f;
+ float delta = GET_WHEEL_DELTA_WPARAM(wParam) / (scaleFactor * static_cast<float>(WHEEL_DELTA));
+ if (isMouseHWheel) {
+ // Windows is <-- -/+ -->, WebKit wants <-- +/- -->, so we negate
+ // |delta| after saving the original value on the wheel tick member.
+ m_wheelTicksX = delta;
+ m_wheelTicksY = 0;
+ delta = -delta;
+ } else {
+ // Even though we use shift + vertical wheel to scroll horizontally in
+ // WebKit, we still note it as a vertical scroll on the wheel tick
+ // member, so that the DOM event we later construct will match the real
+ // hardware event better.
+ m_wheelTicksX = 0;
+ m_wheelTicksY = delta;
+ }
+ if (isMouseHWheel || shiftKey()) {
+ m_deltaX = delta * static_cast<float>(horizontalScrollChars()) * cScrollbarPixelsPerLine;
+ m_deltaY = 0;
+ m_granularity = ScrollByPixelWheelEvent;
+ } else {
+ m_deltaX = 0;
+ m_deltaY = delta;
+ int verticalMultiplier = verticalScrollLines();
+ m_granularity = (verticalMultiplier == WHEEL_PAGESCROLL) ? ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
+ if (m_granularity == ScrollByPixelWheelEvent)
+ m_deltaY *= static_cast<float>(verticalMultiplier) * cScrollbarPixelsPerLine;
+ }
+}
+
+}
diff --git a/Source/WebCore/platform/win/WidgetWin.cpp b/Source/WebCore/platform/win/WidgetWin.cpp
new file mode 100644
index 000000000..9ace1a148
--- /dev/null
+++ b/Source/WebCore/platform/win/WidgetWin.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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 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 "Widget.h"
+
+#include "Chrome.h"
+#include "Cursor.h"
+#include "Document.h"
+#include "Element.h"
+#include "FrameView.h"
+#include "FrameWin.h"
+#include "GraphicsContext.h"
+#include "IntRect.h"
+#include "Page.h"
+
+#include <winsock2.h>
+#include <windows.h>
+
+namespace WebCore {
+
+Widget::Widget(PlatformWidget widget)
+{
+ init(widget);
+}
+
+Widget::~Widget()
+{
+ ASSERT(!parent());
+}
+
+void Widget::show()
+{
+}
+
+void Widget::hide()
+{
+}
+
+bool ignoreNextSetCursor = false;
+
+void Widget::setCursor(const Cursor& cursor)
+{
+ // This is set by PluginViewWin so it can ignore the setCursor call made by
+ // EventHandler.cpp.
+ if (ignoreNextSetCursor) {
+ ignoreNextSetCursor = false;
+ return;
+ }
+
+ FrameView* view = root();
+ if (!view)
+ return;
+ view->hostWindow()->setCursor(cursor);
+}
+
+void Widget::paint(GraphicsContext&, const IntRect&)
+{
+}
+
+void Widget::setFocus(bool focused)
+{
+}
+
+void Widget::setIsSelected(bool)
+{
+}
+
+IntRect Widget::frameRect() const
+{
+ return m_frame;
+}
+
+void Widget::setFrameRect(const IntRect& rect)
+{
+ m_frame = rect;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/Win32Handle.h b/Source/WebCore/platform/win/Win32Handle.h
new file mode 100644
index 000000000..6456042eb
--- /dev/null
+++ b/Source/WebCore/platform/win/Win32Handle.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 Patrick Gansterer <paroga@paroga.com>
+ *
+ * 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 AND ITS CONTRIBUTORS "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 OR ITS 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 Win32Handle_h
+#define Win32Handle_h
+
+#include <memory>
+#include <windows.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class Win32Handle {
+ WTF_MAKE_NONCOPYABLE(Win32Handle);
+public:
+ Win32Handle() : m_handle(INVALID_HANDLE_VALUE) { }
+ explicit Win32Handle(HANDLE handle) : m_handle(handle) { }
+
+ ~Win32Handle() { clear(); }
+
+ void clear()
+ {
+ if (!isValid())
+ return;
+ CloseHandle(m_handle);
+ m_handle = INVALID_HANDLE_VALUE;
+ }
+
+ bool isValid() const { return m_handle != INVALID_HANDLE_VALUE; }
+
+ HANDLE get() const { return m_handle; }
+ HANDLE release() { HANDLE ret = m_handle; m_handle = INVALID_HANDLE_VALUE; return ret; }
+
+ Win32Handle& operator=(HANDLE handle)
+ {
+ clear();
+ m_handle = handle;
+ return *this;
+ }
+
+private:
+ HANDLE m_handle;
+};
+
+} // namespace WebCore
+
+#endif // Win32Handle_h
diff --git a/Source/WebCore/platform/win/WindowMessageBroadcaster.cpp b/Source/WebCore/platform/win/WindowMessageBroadcaster.cpp
new file mode 100644
index 000000000..d10ec5cc3
--- /dev/null
+++ b/Source/WebCore/platform/win/WindowMessageBroadcaster.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007, 2014 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "WindowMessageBroadcaster.h"
+
+#include "WindowMessageListener.h"
+
+namespace WebCore {
+
+typedef HashMap<HWND, WindowMessageBroadcaster*> InstanceMap;
+
+static InstanceMap& instancesMap()
+{
+ static InstanceMap instances;
+ return instances;
+}
+
+void WindowMessageBroadcaster::addListener(HWND hwnd, WindowMessageListener* listener)
+{
+ WindowMessageBroadcaster* broadcaster = instancesMap().get(hwnd);
+ if (!broadcaster) {
+ broadcaster = new WindowMessageBroadcaster(hwnd);
+ instancesMap().add(hwnd, broadcaster);
+ }
+
+ broadcaster->addListener(listener);
+}
+
+void WindowMessageBroadcaster::removeListener(HWND hwnd, WindowMessageListener* listener)
+{
+ WindowMessageBroadcaster* broadcaster = instancesMap().get(hwnd);
+ if (!broadcaster)
+ return;
+
+ broadcaster->removeListener(listener);
+}
+
+WindowMessageBroadcaster::WindowMessageBroadcaster(HWND hwnd)
+ : m_subclassedWindow(hwnd)
+ , m_originalWndProc(0)
+{
+ ASSERT_ARG(hwnd, IsWindow(hwnd));
+}
+
+WindowMessageBroadcaster::~WindowMessageBroadcaster()
+{
+}
+
+void WindowMessageBroadcaster::addListener(WindowMessageListener* listener)
+{
+ if (m_listeners.isEmpty()) {
+ ASSERT(!m_originalWndProc);
+#pragma warning(disable: 4244 4312)
+ m_originalWndProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(m_subclassedWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SubclassedWndProc)));
+ }
+ ASSERT(m_originalWndProc);
+
+ m_listeners.add(listener);
+}
+
+void WindowMessageBroadcaster::removeListener(WindowMessageListener* listener)
+{
+ m_listeners.remove(listener);
+ if (m_listeners.isEmpty())
+ destroy();
+}
+
+void WindowMessageBroadcaster::destroy()
+{
+ m_listeners.clear();
+ unsubclassWindow();
+ instancesMap().remove(m_subclassedWindow);
+ delete this;
+}
+
+void WindowMessageBroadcaster::unsubclassWindow()
+{
+ SetWindowLongPtr(m_subclassedWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_originalWndProc));
+ m_originalWndProc = 0;
+}
+
+LRESULT CALLBACK WindowMessageBroadcaster::SubclassedWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ WindowMessageBroadcaster* broadcaster = instancesMap().get(hwnd);
+ ASSERT(broadcaster);
+ if (!broadcaster)
+ return 0;
+
+ ListenerSet::const_iterator end = broadcaster->listeners().end();
+ for (ListenerSet::const_iterator it = broadcaster->listeners().begin(); it != end; ++it)
+ (*it)->windowReceivedMessage(hwnd, message, wParam, lParam);
+
+ WNDPROC originalWndProc = broadcaster->originalWndProc();
+
+ // This will delete broadcaster.
+ if (message == WM_DESTROY)
+ broadcaster->destroy();
+
+ return CallWindowProc(originalWndProc, hwnd, message, wParam, lParam);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/win/WindowMessageBroadcaster.h b/Source/WebCore/platform/win/WindowMessageBroadcaster.h
new file mode 100644
index 000000000..3dd174523
--- /dev/null
+++ b/Source/WebCore/platform/win/WindowMessageBroadcaster.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 WindowMessageBroadcaster_h
+#define WindowMessageBroadcaster_h
+
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+ class WindowMessageListener;
+
+ class WindowMessageBroadcaster {
+ WTF_MAKE_NONCOPYABLE(WindowMessageBroadcaster);
+ public:
+ static void addListener(HWND, WindowMessageListener*);
+ static void removeListener(HWND, WindowMessageListener*);
+
+ private:
+ typedef HashSet<WindowMessageListener*> ListenerSet;
+
+ static LRESULT CALLBACK SubclassedWndProc(HWND, UINT, WPARAM, LPARAM);
+
+ WindowMessageBroadcaster(HWND);
+ ~WindowMessageBroadcaster();
+
+ void addListener(WindowMessageListener*);
+ void removeListener(WindowMessageListener*);
+ const ListenerSet& listeners() const { return m_listeners; }
+
+ void destroy();
+ void unsubclassWindow();
+
+ WNDPROC originalWndProc() const { return m_originalWndProc; }
+
+ HWND m_subclassedWindow;
+ WNDPROC m_originalWndProc;
+ ListenerSet m_listeners;
+ };
+
+} // namespace WebCore
+
+#endif // WindowMessageBroadcaster_h
diff --git a/Source/WebCore/platform/win/WindowMessageListener.h b/Source/WebCore/platform/win/WindowMessageListener.h
new file mode 100644
index 000000000..4bef2b6a6
--- /dev/null
+++ b/Source/WebCore/platform/win/WindowMessageListener.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 WindowMessageListener_h
+#define WindowMessageListener_h
+
+#include <windows.h>
+
+namespace WebCore {
+
+ class WindowMessageListener {
+ public:
+ virtual void windowReceivedMessage(HWND, UINT message, WPARAM, LPARAM) = 0;
+ };
+
+} // namespace WebCore
+
+#endif // WindowMessageListener_h
diff --git a/Source/WebCore/platform/win/WindowsTouch.h b/Source/WebCore/platform/win/WindowsTouch.h
new file mode 100644
index 000000000..bb482c8ea
--- /dev/null
+++ b/Source/WebCore/platform/win/WindowsTouch.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009, 2015 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 WindowsTouch_h
+#define WindowsTouch_h
+
+/*
+ * The following constants are used to determine multitouch and gesture behavior
+ * for Windows 7. For more information, see:
+ * http://msdn.microsoft.com/en-us/library/dd562197(VS.85).aspx
+ */
+
+// Value used in WebViewWndProc for Gestures
+#define WM_GESTURE 0x0119
+#define WM_GESTURENOTIFY 0x011A
+
+// Gesture Information Flags
+#define GF_BEGIN 0x00000001
+#define GF_INERTIA 0x00000002
+#define GF_END 0x00000004
+
+// Gesture IDs
+#define GID_BEGIN 1
+#define GID_END 2
+#define GID_ZOOM 3
+#define GID_PAN 4
+#define GID_ROTATE 5
+#define GID_TWOFINGERTAP 6
+#define GID_PRESSANDTAP 7
+#define GID_ROLLOVER GID_PRESSANDTAP
+
+// Zoom Gesture Confiration Flags
+#define GC_ZOOM 0x00000001
+
+// Pan Gesture Configuration Flags
+#define GC_PAN 0x00000001
+#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002
+#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
+#define GC_PAN_WITH_GUTTER 0x00000008
+#define GC_PAN_WITH_INERTIA 0x00000010
+
+// Rotate Gesture Configuration Flags
+#define GC_ROTATE 0x00000001
+
+// Two finger tap configuration flags
+#define GC_TWOFINGERTAP 0x00000001
+
+// Press and tap Configuration Flags
+#define GC_PRESSANDTAP 0x00000001
+#define GC_ROLLOVER GC_PRESSANDTAP
+
+#if WINVER < 0x0601
+
+// GESTUREINFO struct definition
+typedef struct tagGESTUREINFO {
+ UINT cbSize; // size, in bytes, of this structure (including variable length Args field)
+ DWORD dwFlags; // see GF_* flags
+ DWORD dwID; // gesture ID, see GID_* defines
+ HWND hwndTarget; // handle to window targeted by this gesture
+ POINTS ptsLocation; // current location of this gesture
+ DWORD dwInstanceID; // internally used
+ DWORD dwSequenceID; // internally used
+ ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES
+ UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture
+} GESTUREINFO, *PGESTUREINFO;
+typedef GESTUREINFO const * PCGESTUREINFO;
+
+// GESTURECONFIG struct defintion
+typedef struct tagGESTURECONFIG {
+ DWORD dwID; // gesture ID
+ DWORD dwWant; // settings related to gesture ID that are to be turned on
+ DWORD dwBlock; // settings related to gesture ID that are to be turned off
+} GESTURECONFIG, *PGESTURECONFIG;
+
+/*
+ * Gesture notification structure
+ * - The WM_GESTURENOTIFY message lParam contains a pointer to this structure.
+ * - The WM_GESTURENOTIFY message notifies a window that gesture recognition is
+ * in progress and a gesture will be generated if one is recognized under the
+ * current gesture settings.
+ */
+typedef struct tagGESTURENOTIFYSTRUCT {
+ UINT cbSize; // size, in bytes, of this structure
+ DWORD dwFlags; // unused
+ HWND hwndTarget; // handle to window targeted by the gesture
+ POINTS ptsLocation; // starting location
+ DWORD dwInstanceID; // internally used
+} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT;
+
+DECLARE_HANDLE(HGESTUREINFO);
+
+#endif
+
+#endif
diff --git a/Source/WebCore/platform/win/makesafeseh.asm b/Source/WebCore/platform/win/makesafeseh.asm
new file mode 100644
index 000000000..32fcfaf24
--- /dev/null
+++ b/Source/WebCore/platform/win/makesafeseh.asm
@@ -0,0 +1,45 @@
+;/*
+; * Copyright (C) 2013 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.
+; */
+
+; Tell Windows to trust our error handler. This must be done within an assembly
+; module. We cannot do it on-the-fly in our C++ code.
+;
+; Note also (confirmed by Raymond Chen) that we must use this assembly thunk
+; to call our custom exception handler. (See http://jpassing.com/2008/05/20/fun-with-low-level-seh/)
+
+.386
+.model FLAT, STDCALL
+
+EXTERN exceptionHandler@16 : near ; Defined in StructuredExceptionHandlerSuppressor.cpp
+
+exceptionHandlerThunk proto
+.safeseh exceptionHandlerThunk
+
+.code
+exceptionHandlerThunk proc
+ jmp exceptionHandler@16
+exceptionHandlerThunk endp
+
+END \ No newline at end of file
diff --git a/Source/WebKit/PlatformQt.cmake b/Source/WebKit/PlatformQt.cmake
index aa95a86e0..6b6e0562e 100644
--- a/Source/WebKit/PlatformQt.cmake
+++ b/Source/WebKit/PlatformQt.cmake
@@ -392,17 +392,38 @@ install(
set(WEBKIT_PKGCONGIG_DEPS "Qt5Core Qt5Gui Qt5Network")
set(WEBKIT_PRI_DEPS "core gui network")
-set(WEBKIT_PRI_RUNTIME_DEPS "sensors positioning qml quick webchannel core_private gui_private")
set(WEBKIT_PRI_EXTRA_LIBS "")
-set(WEBKITWIDGETS_PKGCONGIG_DEPS "Qt5Core Qt5Gui Qt5Network Qt5Widgets Qt5WebKit")
-set(WEBKITWIDGETS_PRI_DEPS "core gui network widgets webkit")
-set(WEBKITWIDGETS_PRI_RUNTIME_DEPS "sensors positioning widgets_private opengl sql core_private gui_private")
+set(WEBKIT_PRI_RUNTIME_DEPS "core_private gui_private")
+
+if (QT_WEBCHANNEL)
+ set(WEBKIT_PRI_RUNTIME_DEPS "webchannel ${WEBKIT_PRI_RUNTIME_DEPS}")
+endif ()
+if (ENABLE_WEBKIT2)
+ set(WEBKIT_PRI_RUNTIME_DEPS "qml quick ${WEBKIT_PRI_RUNTIME_DEPS}")
+endif ()
+if (ENABLE_GEOLOCATION)
+ set(WEBKIT_PRI_RUNTIME_DEPS "positioning ${WEBKIT_PRI_RUNTIME_DEPS}")
+endif ()
+if (ENABLE_DEVICE_ORIENTATION)
+ set(WEBKIT_PRI_RUNTIME_DEPS "sensors ${WEBKIT_PRI_RUNTIME_DEPS}")
+endif ()
+
+set(WEBKITWIDGETS_PKGCONGIG_DEPS "${WEBKIT_PKGCONGIG_DEPS} Qt5Widgets Qt5WebKit")
+set(WEBKITWIDGETS_PRI_DEPS "${WEBKIT_PRI_DEPS} widgets webkit")
+set(WEBKITWIDGETS_PRI_RUNTIME_DEPS "${WEBKIT_PRI_RUNTIME_DEPS} widgets_private")
+
+if (Qt5OpenGL_FOUND)
+ set(WEBKITWIDGETS_PRI_RUNTIME_DEPS "${WEBKITWIDGETS_PRI_RUNTIME_DEPS} opengl")
+endif ()
+
+if (ENABLE_PRINT_SUPPORT)
+ set(WEBKITWIDGETS_PRI_RUNTIME_DEPS "${WEBKITWIDGETS_PRI_RUNTIME_DEPS} printsupport")
+endif ()
+
if (QT_STATIC_BUILD)
if (MSVC)
set(LIB_PREFIX "lib")
endif ()
- set(WEBKIT_PKGCONGIG_DEPS "${WEBKIT_PKGCONGIG_DEPS} Qt5Sql")
- set(WEBKIT_PRI_DEPS "${WEBKIT_PRI_DEPS} sql")
set(WEBKITWIDGETS_PKGCONGIG_DEPS "${WEBKITWIDGETS_PKGCONGIG_DEPS} Qt5PrintSupport")
set(WEBKITWIDGETS_PRI_DEPS "${WEBKITWIDGETS_PRI_DEPS} printsupport")
set(EXTRA_LIBS_NAMES WebCore JavaScriptCore WTF xml2)
@@ -428,9 +449,6 @@ if (QT_STATIC_BUILD)
set(WEBKIT_PKGCONGIG_DEPS "${WEBKIT_PKGCONGIG_DEPS} ${LIB_PREFIX}${LIB_NAME}")
set(WEBKIT_PRI_EXTRA_LIBS "${WEBKIT_PRI_EXTRA_LIBS} -l${LIB_PREFIX}${LIB_NAME}")
endforeach ()
-else ()
- set(WEBKIT_PRI_RUNTIME_DEPS "${WEBKIT_PRI_RUNTIME_DEPS} sql")
- set(WEBKITWIDGETS_PRI_RUNTIME_DEPS "${WEBKITWIDGETS_PRI_RUNTIME_DEPS} printsupport")
endif ()
if (NOT MACOS_BUILD_FRAMEWORKS)
@@ -445,12 +463,13 @@ endif ()
if (KDE_INSTALL_USE_QT_SYS_PATHS)
set(WebKit_PRI_ARGUMENTS
+ BIN_INSTALL_DIR "$$QT_MODULE_BIN_BASE"
LIB_INSTALL_DIR "$$QT_MODULE_LIB_BASE"
)
if (MACOS_BUILD_FRAMEWORKS)
list(APPEND WebKit_PRI_ARGUMENTS
INCLUDE_INSTALL_DIR "$$QT_MODULE_LIB_BASE/QtWebKit.framework/Headers"
- MODULE_CONFIG "v2 lib_bundle"
+ MODULE_CONFIG "lib_bundle"
)
else ()
list(APPEND WebKit_PRI_ARGUMENTS
@@ -465,7 +484,7 @@ else ()
if (MACOS_BUILD_FRAMEWORKS)
list(APPEND WebKit_PRI_ARGUMENTS
INCLUDE_INSTALL_DIR "${LIB_INSTALL_DIR}/QtWebKit.framework/Headers"
- MODULE_CONFIG "v2 lib_bundle"
+ MODULE_CONFIG "lib_bundle"
)
else ()
list(APPEND WebKit_PRI_ARGUMENTS
@@ -483,6 +502,7 @@ endif ()
ecm_generate_pri_file(
BASE_NAME webkit
+ NAME QtWebKit
LIB_NAME ${WebKit_OUTPUT_NAME}
INCLUDE_INSTALL_DIR "${KDE_INSTALL_INCLUDEDIR}/QtWebKit"
DEPS "${WEBKIT_PRI_DEPS}"
@@ -633,12 +653,13 @@ endif ()
if (KDE_INSTALL_USE_QT_SYS_PATHS)
set(WebKitWidgets_PRI_ARGUMENTS
+ BIN_INSTALL_DIR "$$QT_MODULE_BIN_BASE"
LIB_INSTALL_DIR "$$QT_MODULE_LIB_BASE"
)
if (MACOS_BUILD_FRAMEWORKS)
list(APPEND WebKitWidgets_PRI_ARGUMENTS
INCLUDE_INSTALL_DIR "$$QT_MODULE_LIB_BASE/QtWebKitWidgets.framework/Headers"
- MODULE_CONFIG "v2 lib_bundle"
+ MODULE_CONFIG "lib_bundle"
)
else ()
list(APPEND WebKitWidgets_PRI_ARGUMENTS
@@ -653,7 +674,7 @@ else ()
if (MACOS_BUILD_FRAMEWORKS)
list(APPEND WebKitWidgets_PRI_ARGUMENTS
INCLUDE_INSTALL_DIR "${LIB_INSTALL_DIR}/QtWebKitWidgets.framework/Headers"
- MODULE_CONFIG "v2 lib_bundle"
+ MODULE_CONFIG "lib_bundle"
)
else ()
list(APPEND WebKitWidgets_PRI_ARGUMENTS
@@ -671,6 +692,7 @@ endif ()
ecm_generate_pri_file(
BASE_NAME webkitwidgets
+ NAME QtWebKitWidgets
LIB_NAME ${WebKitWidgets_OUTPUT_NAME}
INCLUDE_INSTALL_DIR "${KDE_INSTALL_INCLUDEDIR}/QtWebKitWidgets"
DEPS "${WEBKITWIDGETS_PRI_DEPS}"
diff --git a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
index 76038cbc0..50f91e203 100644
--- a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
+++ b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
@@ -565,9 +565,8 @@ void FrameLoaderClientQt::finishedLoading(DocumentLoader*)
{
if (!m_pluginView)
return;
- if (m_pluginView->isPluginView())
- m_pluginView->didFinishLoading();
- m_pluginView = 0;
+ m_pluginView->didFinishLoading();
+ m_pluginView = nullptr;
m_hasSentResponseToPlugin = false;
}
@@ -803,8 +802,7 @@ void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader,
{
if (!m_pluginView)
return;
- if (m_pluginView->isPluginView())
- m_pluginView->didFail(error);
+ m_pluginView->didFail(error);
m_pluginView = 0;
m_hasSentResponseToPlugin = false;
}
@@ -820,7 +818,7 @@ void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const c
loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
// We re-check here as the plugin can have been created.
- if (m_pluginView && m_pluginView->isPluginView()) {
+ if (m_pluginView) {
if (!m_hasSentResponseToPlugin) {
m_pluginView->didReceiveResponse(loader->response());
// The function didReceiveResponse sets up a new stream to the plug-in.
@@ -1496,9 +1494,12 @@ RefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTML
void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget)
{
+ if (!pluginWidget || !pluginWidget->isPluginView()) {
+ m_pluginView = nullptr;
+ return;
+ }
m_pluginView = toPluginView(pluginWidget);
- if (pluginWidget)
- m_hasSentResponseToPlugin = false;
+ m_hasSentResponseToPlugin = false;
}
PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues)
diff --git a/Source/WebKit/qt/tests/CMakeLists.txt b/Source/WebKit/qt/tests/CMakeLists.txt
index 685896bfe..2691196b3 100644
--- a/Source/WebKit/qt/tests/CMakeLists.txt
+++ b/Source/WebKit/qt/tests/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.12)
+remove_definitions(-DQT_ASCII_CAST_WARNINGS)
include_directories(
"${CMAKE_SOURCE_DIR}/Source"
diff --git a/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp b/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp
index 9d6425ad6..17488ebb9 100644
--- a/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp
+++ b/Source/WebKit/qt/tests/qwebhistory/tst_qwebhistory.cpp
@@ -126,7 +126,7 @@ void tst_QWebHistory::count()
void tst_QWebHistory::back()
{
for (int i = histsize;i > 1;i--) {
- QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i));
+ QCOMPARE(page->mainFrame()->toPlainText(), QStringLiteral("page%1").arg(i));
hist->back();
loadFinishedBarrier->ensureSignalEmitted();
}
@@ -147,13 +147,13 @@ void tst_QWebHistory::forward()
}
for (int i = 1;i < histsize;i++) {
- QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i));
+ QCOMPARE(page->mainFrame()->toPlainText(), QStringLiteral("page%1").arg(i));
hist->forward();
loadFinishedBarrier->ensureSignalEmitted();
}
//try one more time (too many). crash test
hist->forward();
- QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(histsize));
+ QCOMPARE(page->mainFrame()->toPlainText(), QStringLiteral("page%1").arg(histsize));
}
/**
@@ -162,7 +162,7 @@ void tst_QWebHistory::forward()
void tst_QWebHistory::itemAt()
{
for (int i = 1;i < histsize;i++) {
- QCOMPARE(hist->itemAt(i - 1).title(), QString("page") + QString::number(i));
+ QCOMPARE(hist->itemAt(i - 1).title(), QStringLiteral("page%1").arg(i));
QVERIFY(hist->itemAt(i - 1).isValid());
}
//check out of range values
@@ -197,7 +197,7 @@ void tst_QWebHistory::items()
//check order
for (int i = 1;i <= histsize;i++) {
- QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
+ QCOMPARE(items.at(i - 1).title(), QStringLiteral("page%1").arg(i));
}
}
@@ -226,7 +226,7 @@ void tst_QWebHistory::serialize_1()
//check order of historyItems
QList<QWebHistoryItem> items = hist->items();
for (int i = 1;i <= histsize;i++) {
- QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
+ QCOMPARE(items.at(i - 1).title(), QStringLiteral("page%1").arg(i));
}
}
@@ -241,7 +241,7 @@ void tst_QWebHistory::serialize_2()
QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded
// Force a "same document" navigation.
- frame->load(frame->url().toString() + QLatin1String("#dummyAnchor"));
+ frame->load(QUrl(frame->url().toString() + QLatin1String("#dummyAnchor")));
int initialCurrentIndex = hist->currentItemIndex();
diff --git a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
index 67fe242f9..e545c5c0f 100644
--- a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
+++ b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
@@ -596,8 +596,8 @@ void tst_QWebPage::userStyleSheet()
TestNetworkManager* networkManager = new TestNetworkManager(m_page);
m_page->setNetworkAccessManager(networkManager);
- m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64,"
- + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64()));
+ m_page->settings()->setUserStyleSheetUrl(QUrl(QString::fromLatin1("data:text/css;charset=utf-8;base64,"
+ + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64())));
m_view->setHtml("<p>hello world</p>");
QVERIFY(::waitForSignal(m_view, SIGNAL(loadFinished(bool))));
diff --git a/Source/cmake/ECMGeneratePriFile.cmake b/Source/cmake/ECMGeneratePriFile.cmake
index fdee5504d..d74eabc70 100644
--- a/Source/cmake/ECMGeneratePriFile.cmake
+++ b/Source/cmake/ECMGeneratePriFile.cmake
@@ -106,7 +106,7 @@ endif()
function(ECM_GENERATE_PRI_FILE)
set(options )
- set(oneValueArgs BASE_NAME LIB_NAME DEPS RUNTIME_DEPS FILENAME_VAR INCLUDE_INSTALL_DIR INCLUDE_INSTALL_DIR2 LIB_INSTALL_DIR SET_RPATH DEFINES QT_MODULES EXTRA_LIBS MODULE_CONFIG)
+ set(oneValueArgs BASE_NAME LIB_NAME DEPS RUNTIME_DEPS FILENAME_VAR INCLUDE_INSTALL_DIR INCLUDE_INSTALL_DIR2 LIB_INSTALL_DIR SET_RPATH DEFINES QT_MODULES EXTRA_LIBS MODULE_CONFIG NAME BIN_INSTALL_DIR)
set(multiValueArgs )
cmake_parse_arguments(EGPF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@@ -142,6 +142,15 @@ function(ECM_GENERATE_PRI_FILE)
set(EGPF_LIB_INSTALL_DIR "lib")
endif()
endif()
+ if(NOT EGPF_BIN_INSTALL_DIR)
+ if(BIN_INSTALL_DIR)
+ set(EGPF_BIN_INSTALL_DIR "${BIN_INSTALL_DIR}")
+ elseif(CMAKE_INSTALL_BINDIR)
+ set(EGPF_BIN_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}")
+ else()
+ set(EGPF_BIN_INSTALL_DIR "bin")
+ endif()
+ endif()
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" PROJECT_VERSION_MAJOR "${PROJECT_VERSION_STRING}")
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" PROJECT_VERSION_MINOR "${PROJECT_VERSION_STRING}")
@@ -168,6 +177,11 @@ function(ECM_GENERATE_PRI_FILE)
else()
set(PRI_TARGET_LIBS "${CMAKE_INSTALL_PREFIX}/${EGPF_LIB_INSTALL_DIR}")
endif()
+ if(IS_ABSOLUTE "${EGPF_BIN_INSTALL_DIR}" OR "${EGPF_BIN_INSTALL_DIR}" MATCHES "^\\$\\$")
+ set(PRI_TARGET_BINS "${EGPF_BIN_INSTALL_DIR}")
+ else()
+ set(PRI_TARGET_BINS "${CMAKE_INSTALL_PREFIX}/${EGPF_BIN_INSTALL_DIR}")
+ endif()
if (EGPF_SET_RPATH)
set(PRI_TARGET_RPATH ${PRI_TARGET_LIBS})
else()
@@ -195,6 +209,12 @@ function(ECM_GENERATE_PRI_FILE)
set(PRI_TARGET_FRAMEWORKS "")
endif ()
+ if (EGPF_NAME)
+ set(PRI_TARGET_NAME ${EGPF_NAME})
+ else ()
+ set(PRI_TARGET_NAME ${PRI_TARGET_LIBNAME})
+ endif ()
+
file(GENERATE
OUTPUT ${PRI_FILENAME}
CONTENT
@@ -202,7 +222,7 @@ function(ECM_GENERATE_PRI_FILE)
QT.${PRI_TARGET_BASENAME}.MAJOR_VERSION = ${PROJECT_VERSION_MAJOR}
QT.${PRI_TARGET_BASENAME}.MINOR_VERSION = ${PROJECT_VERSION_MINOR}
QT.${PRI_TARGET_BASENAME}.PATCH_VERSION = ${PROJECT_VERSION_PATCH}
-QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_LIBNAME}
+QT.${PRI_TARGET_BASENAME}.name = ${PRI_TARGET_NAME}
QT.${PRI_TARGET_BASENAME}.module = ${PRI_TARGET_LIBNAME}
QT.${PRI_TARGET_BASENAME}.DEFINES = ${PRI_TARGET_DEFINES}
QT.${PRI_TARGET_BASENAME}.includes = \"${PRI_TARGET_INCLUDES}\" \"${PRI_TARGET_INCLUDES2}\"
@@ -211,13 +231,13 @@ QT.${PRI_TARGET_BASENAME}.libs = \"${PRI_TARGET_LIBS}\"
QT.${PRI_TARGET_BASENAME}.rpath = \"${PRI_TARGET_RPATH}\"
QT.${PRI_TARGET_BASENAME}.depends = ${PRI_TARGET_QTDEPS}
QT.${PRI_TARGET_BASENAME}.run_depends = ${PRI_TARGET_QTRUNDEPS}
-QT.${PRI_TARGET_BASENAME}.bins =
+QT.${PRI_TARGET_BASENAME}.bins = ${PRI_TARGET_BINS}
QT.${PRI_TARGET_BASENAME}.libexec =
QT.${PRI_TARGET_BASENAME}.plugins =
QT.${PRI_TARGET_BASENAME}.imports =
QT.${PRI_TARGET_BASENAME}.qml =
QT.${PRI_TARGET_BASENAME}.frameworks = ${PRI_TARGET_FRAMEWORKS}
-QT.${PRI_TARGET_BASENAME}.module_config = ${PRI_TARGET_CONFIG}
+QT.${PRI_TARGET_BASENAME}.module_config = v2 ${PRI_TARGET_CONFIG}
QT_MODULES += ${PRI_TARGET_QT_MODULES}
QMAKE_LIBS_PRIVATE += ${PRI_TARGET_EXTRA_LIBS}
QMAKE_RPATHDIR += ${PRI_TARGET_RPATH}
diff --git a/Source/cmake/KDEInstallDirs.cmake b/Source/cmake/KDEInstallDirs.cmake
index 4248c859d..f41f2b8b6 100644
--- a/Source/cmake/KDEInstallDirs.cmake
+++ b/Source/cmake/KDEInstallDirs.cmake
@@ -445,6 +445,10 @@ if(KDE_INSTALL_USE_QT_SYS_PATHS)
set(CMAKECONFIG_INSTALL_PREFIX "${LIB_INSTALL_DIR}/cmake")
set(KDE_INSTALL_CMAKEPACKAGEDIR "${LIB_INSTALL_DIR}/cmake")
+ query_qmake(qt_include_dir QT_INSTALL_HEADERS)
+ file(RELATIVE_PATH INCLUDE_INSTALL_DIR ${qt_install_prefix} ${qt_include_dir})
+ set(KDE_INSTALL_INCLUDEDIR ${INCLUDE_INSTALL_DIR})
+
# Qt-specific vars
query_qmake(qt_plugins_dir QT_INSTALL_PLUGINS)
diff --git a/Source/cmake/OptionsCommon.cmake b/Source/cmake/OptionsCommon.cmake
index 6a32559a0..4529bdd84 100644
--- a/Source/cmake/OptionsCommon.cmake
+++ b/Source/cmake/OptionsCommon.cmake
@@ -29,8 +29,8 @@ endif ()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if (COMPILER_IS_GCC_OR_CLANG)
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fno-exceptions -fno-strict-aliasing")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-strict-aliasing -fno-rtti")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-exceptions -fno-strict-aliasing")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-strict-aliasing -fno-rtti")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif ()
diff --git a/Source/cmake/OptionsQt.cmake b/Source/cmake/OptionsQt.cmake
index f73bc4146..cec1a3d1b 100644
--- a/Source/cmake/OptionsQt.cmake
+++ b/Source/cmake/OptionsQt.cmake
@@ -1,6 +1,5 @@
include(FeatureSummary)
include(ECMPackageConfigHelpers)
-include(ECMQueryQmake)
set(ECM_MODULE_DIR ${CMAKE_MODULE_PATH})
@@ -57,6 +56,15 @@ set(PROJECT_VERSION_STRING "${PROJECT_VERSION}")
set(CMAKE_MACOSX_RPATH ON)
add_definitions(-DBUILDING_QT__=1)
+add_definitions(-DQT_NO_EXCEPTIONS)
+add_definitions(-DQT_USE_QSTRINGBUILDER)
+add_definitions(-DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS)
+add_definitions(-DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x050000)
+
+# We use -fno-rtti with GCC and Clang, see OptionsCommon.cmake
+if (COMPILER_IS_GCC_OR_CLANG)
+ add_definitions(-DQT_NO_DYNAMIC_CAST)
+endif ()
if (WIN32)
if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
@@ -368,7 +376,7 @@ if (WEBP_FOUND)
endif ()
set(REQUIRED_QT_VERSION 5.2.0)
-set(QT_REQUIRED_COMPONENTS Core Gui Network Sql)
+set(QT_REQUIRED_COMPONENTS Core Gui Network)
# FIXME: Allow building w/o these components
list(APPEND QT_REQUIRED_COMPONENTS
@@ -446,7 +454,7 @@ set(CMAKE_AUTOMOC ON)
if (COMPILER_IS_GCC_OR_CLANG AND UNIX)
if (NOT APPLE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fno-rtti")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--gc-sections")
endif ()
@@ -700,6 +708,9 @@ set_package_properties(Ruby PROPERTIES TYPE REQUIRED)
set_package_properties(Qt5PrintSupport PROPERTIES PURPOSE "Required for ENABLE_PRINT_SUPPORT=ON")
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+
+include(ECMQueryQmake)
+
query_qmake(qt_install_prefix_dir QT_INSTALL_PREFIX)
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${qt_install_prefix_dir}" CACHE PATH "Install path prefix, prepended onto install directories." FORCE)
diff --git a/Tools/PlatformQt.cmake b/Tools/PlatformQt.cmake
index 5b1783887..311156446 100644
--- a/Tools/PlatformQt.cmake
+++ b/Tools/PlatformQt.cmake
@@ -1,3 +1,5 @@
+remove_definitions(-DQT_ASCII_CAST_WARNINGS)
+
add_subdirectory(QtTestBrowser)
if (ENABLE_API_TESTS)
diff --git a/Tools/qmake/projects/run_cmake.pro b/Tools/qmake/projects/run_cmake.pro
index 45d97e976..4b47f54f4 100644
--- a/Tools/qmake/projects/run_cmake.pro
+++ b/Tools/qmake/projects/run_cmake.pro
@@ -73,6 +73,11 @@ build_pass|!debug_and_release {
}
exists($$QMAKE_MAC_SDK_PATH): CMAKE_CONFIG += CMAKE_OSX_SYSROOT=$$QMAKE_MAC_SDK_PATH
!isEmpty(QMAKE_MACOSX_DEPLOYMENT_TARGET): CMAKE_CONFIG += CMAKE_OSX_DEPLOYMENT_TARGET=$$QMAKE_MACOSX_DEPLOYMENT_TARGET
+
+ # Hack: install frameworks in debug_and_release in separate prefixes
+ debug_and_release:build_all:CONFIG(debug, debug|release) {
+ CMAKE_CONFIG += CMAKE_INSTALL_PREFIX=\"$$[QT_INSTALL_PREFIX]/debug\"
+ }
}
equals(QMAKE_HOST.os, Windows) {
@@ -112,17 +117,13 @@ build_pass|!debug_and_release {
QMAKE_EXTRA_TARGETS += default_target
# When debug and release are built at the same time, don't install data files twice
- debug_and_release:build_all:CONFIG(debug, debug|release) {
- cmake_install_args = "-DCOMPONENT=Code"
- # TODO: Fix macOS frameworks installation in debug_and_release
- macos: destdir_suffix = "/debug"
- }
+ debug_and_release:build_all:CONFIG(debug, debug|release): cmake_install_args = "-DCOMPONENT=Code"
install_impl_target.target = install_impl
install_impl_target.commands = cd $$cmake_build_dir && cmake $$cmake_install_args -P cmake_install.cmake
QMAKE_EXTRA_TARGETS += install_impl_target
install_target.target = install
- install_target.commands = $(MAKE) -f $(MAKEFILE) install_impl $$make_args DESTDIR=$(INSTALL_ROOT)$$destdir_suffix
+ install_target.commands = $(MAKE) -f $(MAKEFILE) install_impl $$make_args DESTDIR=$(INSTALL_ROOT)
QMAKE_EXTRA_TARGETS += install_target
}
diff --git a/Tools/qt/manifest.txt b/Tools/qt/manifest.txt
index 8ae73e35f..8affd54a2 100644
--- a/Tools/qt/manifest.txt
+++ b/Tools/qt/manifest.txt
@@ -73,13 +73,9 @@ file Source/WTF/wtf/threads/win/BinarySemaphoreWin.cpp
file Source/WTF/wtf/win
file Source/WebCore/platform/graphics/win/LocalWindowsContext.h
file Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.cpp
+file Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h
file Source/WebCore/platform/graphics/win/TransformationMatrixWin.cpp
-file Source/WebCore/platform/win/BitmapInfo.cpp
-file Source/WebCore/platform/win/BitmapInfo.h
-file Source/WebCore/platform/win/SystemInfo.cpp
-file Source/WebCore/platform/win/SystemInfo.h
-file Source/WebCore/platform/win/WebCoreInstanceHandle.cpp
-file Source/WebCore/platform/win/WebCoreInstanceHandle.h
+file Source/WebCore/platform/win
# macOS-specific code
file Source/WTF/wtf/cf