From bd3f57b00bee3088971209a0ebc513eb1ef4ba14 Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Fri, 21 Apr 2017 06:12:49 +0300 Subject: Import WebKit commit 584c4a7a6a8bffb60f03b9eb10a65dbcf41dc0b7 Change-Id: Ife943bbbd8226afa05ef6320b10ba351d55fd797 Reviewed-by: Konstantin Tokarev --- .../JavaScriptCore/bytecompiler/NodesCodegen.cpp | 2 +- Source/JavaScriptCore/ftl/FTLState.cpp | 2 +- .../indexeddb/server/SQLiteIDBBackingStore.cpp | 2 +- Source/WebCore/PlatformQt.cmake | 4 +- .../win/MediaPlayerPrivateMediaFoundation.h | 487 +++++++ Source/WebCore/platform/network/qt/CookieJarQt.cpp | 120 +- Source/WebCore/platform/network/qt/CookieJarQt.h | 7 +- Source/WebCore/platform/win/BString.cpp | 197 +++ Source/WebCore/platform/win/BString.h | 83 ++ Source/WebCore/platform/win/COMPtr.h | 245 ++++ .../WebCore/platform/win/ClipboardUtilitiesWin.cpp | 841 ++++++++++++ .../WebCore/platform/win/ClipboardUtilitiesWin.h | 89 ++ Source/WebCore/platform/win/CursorWin.cpp | 296 ++++ .../WebCore/platform/win/DefWndProcWindowClass.cpp | 52 + .../WebCore/platform/win/DefWndProcWindowClass.h | 38 + .../platform/win/DelayLoadedModulesEnumerator.cpp | 86 ++ .../platform/win/DelayLoadedModulesEnumerator.h | 56 + Source/WebCore/platform/win/DragDataWin.cpp | 210 +++ Source/WebCore/platform/win/DragImageCGWin.cpp | 149 ++ Source/WebCore/platform/win/DragImageCairoWin.cpp | 177 +++ Source/WebCore/platform/win/DragImageWin.cpp | 217 +++ Source/WebCore/platform/win/EventLoopWin.cpp | 45 + Source/WebCore/platform/win/FileSystemWin.cpp | 450 +++++++ Source/WebCore/platform/win/GDIObjectCounter.cpp | 74 + Source/WebCore/platform/win/GDIObjectCounter.h | 63 + Source/WebCore/platform/win/GDIUtilities.cpp | 39 + Source/WebCore/platform/win/GDIUtilities.h | 37 + Source/WebCore/platform/win/HWndDC.h | 89 ++ .../platform/win/ImportedFunctionsEnumerator.cpp | 75 ++ .../platform/win/ImportedFunctionsEnumerator.h | 58 + .../platform/win/ImportedModulesEnumerator.cpp | 73 + .../platform/win/ImportedModulesEnumerator.h | 52 + .../platform/win/ImportedModulesEnumeratorBase.h | 47 + Source/WebCore/platform/win/KeyEventWin.cpp | 255 ++++ Source/WebCore/platform/win/LanguageWin.cpp | 77 ++ .../WebCore/platform/win/LocalizedStringsWin.cpp | 62 + Source/WebCore/platform/win/LoggingWin.cpp | 55 + .../WebCore/platform/win/MIMETypeRegistryWin.cpp | 115 ++ .../platform/win/MainThreadSharedTimerWin.cpp | 198 +++ .../platform/win/MemoryPressureHandlerWin.cpp | 135 ++ Source/WebCore/platform/win/PEImage.cpp | 74 + Source/WebCore/platform/win/PEImage.h | 54 + Source/WebCore/platform/win/PasteboardWin.cpp | 1060 +++++++++++++++ Source/WebCore/platform/win/PathWalker.cpp | 51 + Source/WebCore/platform/win/PathWalker.h | 51 + .../WebCore/platform/win/PlatformMouseEventWin.cpp | 125 ++ Source/WebCore/platform/win/PlatformScreenWin.cpp | 104 ++ Source/WebCore/platform/win/PopupMenuWin.cpp | 1422 ++++++++++++++++++++ Source/WebCore/platform/win/PopupMenuWin.h | 189 +++ Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp | 100 ++ Source/WebCore/platform/win/ScrollbarThemeWin.cpp | 403 ++++++ Source/WebCore/platform/win/ScrollbarThemeWin.h | 62 + Source/WebCore/platform/win/SearchPopupMenuWin.cpp | 101 ++ Source/WebCore/platform/win/SearchPopupMenuWin.h | 44 + Source/WebCore/platform/win/SharedBufferWin.cpp | 66 + Source/WebCore/platform/win/SoftLinking.h | 322 +++++ Source/WebCore/platform/win/SoundWin.cpp | 36 + .../win/StructuredExceptionHandlerSuppressor.cpp | 143 ++ .../win/StructuredExceptionHandlerSuppressor.h | 53 + Source/WebCore/platform/win/TemporaryLinkStubs.cpp | 45 + Source/WebCore/platform/win/WCDataObject.cpp | 365 +++++ Source/WebCore/platform/win/WCDataObject.h | 78 ++ Source/WebCore/platform/win/WebCoreBundleWin.cpp | 67 + Source/WebCore/platform/win/WebCoreBundleWin.h | 41 + .../WebCore/platform/win/WebCoreTextRenderer.cpp | 117 ++ Source/WebCore/platform/win/WebCoreTextRenderer.h | 49 + Source/WebCore/platform/win/WheelEventWin.cpp | 142 ++ Source/WebCore/platform/win/WidgetWin.cpp | 101 ++ Source/WebCore/platform/win/Win32Handle.h | 68 + .../platform/win/WindowMessageBroadcaster.cpp | 128 ++ .../platform/win/WindowMessageBroadcaster.h | 70 + .../WebCore/platform/win/WindowMessageListener.h | 43 + Source/WebCore/platform/win/WindowsTouch.h | 116 ++ Source/WebCore/platform/win/makesafeseh.asm | 45 + Source/WebKit/PlatformQt.cmake | 48 +- .../qt/WebCoreSupport/FrameLoaderClientQt.cpp | 17 +- Source/WebKit/qt/tests/CMakeLists.txt | 2 +- .../qt/tests/qwebhistory/tst_qwebhistory.cpp | 14 +- Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 4 +- Source/cmake/ECMGeneratePriFile.cmake | 28 +- Source/cmake/KDEInstallDirs.cmake | 4 + Source/cmake/OptionsCommon.cmake | 4 +- Source/cmake/OptionsQt.cmake | 17 +- 83 files changed, 11342 insertions(+), 90 deletions(-) create mode 100644 Source/WebCore/platform/graphics/win/MediaPlayerPrivateMediaFoundation.h create mode 100644 Source/WebCore/platform/win/BString.cpp create mode 100644 Source/WebCore/platform/win/BString.h create mode 100644 Source/WebCore/platform/win/COMPtr.h create mode 100644 Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp create mode 100644 Source/WebCore/platform/win/ClipboardUtilitiesWin.h create mode 100644 Source/WebCore/platform/win/CursorWin.cpp create mode 100644 Source/WebCore/platform/win/DefWndProcWindowClass.cpp create mode 100644 Source/WebCore/platform/win/DefWndProcWindowClass.h create mode 100644 Source/WebCore/platform/win/DelayLoadedModulesEnumerator.cpp create mode 100644 Source/WebCore/platform/win/DelayLoadedModulesEnumerator.h create mode 100644 Source/WebCore/platform/win/DragDataWin.cpp create mode 100644 Source/WebCore/platform/win/DragImageCGWin.cpp create mode 100644 Source/WebCore/platform/win/DragImageCairoWin.cpp create mode 100644 Source/WebCore/platform/win/DragImageWin.cpp create mode 100644 Source/WebCore/platform/win/EventLoopWin.cpp create mode 100644 Source/WebCore/platform/win/FileSystemWin.cpp create mode 100644 Source/WebCore/platform/win/GDIObjectCounter.cpp create mode 100644 Source/WebCore/platform/win/GDIObjectCounter.h create mode 100644 Source/WebCore/platform/win/GDIUtilities.cpp create mode 100644 Source/WebCore/platform/win/GDIUtilities.h create mode 100644 Source/WebCore/platform/win/HWndDC.h create mode 100644 Source/WebCore/platform/win/ImportedFunctionsEnumerator.cpp create mode 100644 Source/WebCore/platform/win/ImportedFunctionsEnumerator.h create mode 100644 Source/WebCore/platform/win/ImportedModulesEnumerator.cpp create mode 100644 Source/WebCore/platform/win/ImportedModulesEnumerator.h create mode 100644 Source/WebCore/platform/win/ImportedModulesEnumeratorBase.h create mode 100644 Source/WebCore/platform/win/KeyEventWin.cpp create mode 100644 Source/WebCore/platform/win/LanguageWin.cpp create mode 100644 Source/WebCore/platform/win/LocalizedStringsWin.cpp create mode 100644 Source/WebCore/platform/win/LoggingWin.cpp create mode 100644 Source/WebCore/platform/win/MIMETypeRegistryWin.cpp create mode 100644 Source/WebCore/platform/win/MainThreadSharedTimerWin.cpp create mode 100644 Source/WebCore/platform/win/MemoryPressureHandlerWin.cpp create mode 100644 Source/WebCore/platform/win/PEImage.cpp create mode 100644 Source/WebCore/platform/win/PEImage.h create mode 100644 Source/WebCore/platform/win/PasteboardWin.cpp create mode 100644 Source/WebCore/platform/win/PathWalker.cpp create mode 100644 Source/WebCore/platform/win/PathWalker.h create mode 100644 Source/WebCore/platform/win/PlatformMouseEventWin.cpp create mode 100644 Source/WebCore/platform/win/PlatformScreenWin.cpp create mode 100644 Source/WebCore/platform/win/PopupMenuWin.cpp create mode 100644 Source/WebCore/platform/win/PopupMenuWin.h create mode 100644 Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp create mode 100644 Source/WebCore/platform/win/ScrollbarThemeWin.cpp create mode 100644 Source/WebCore/platform/win/ScrollbarThemeWin.h create mode 100644 Source/WebCore/platform/win/SearchPopupMenuWin.cpp create mode 100644 Source/WebCore/platform/win/SearchPopupMenuWin.h create mode 100644 Source/WebCore/platform/win/SharedBufferWin.cpp create mode 100644 Source/WebCore/platform/win/SoftLinking.h create mode 100644 Source/WebCore/platform/win/SoundWin.cpp create mode 100644 Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp create mode 100644 Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.h create mode 100644 Source/WebCore/platform/win/TemporaryLinkStubs.cpp create mode 100644 Source/WebCore/platform/win/WCDataObject.cpp create mode 100644 Source/WebCore/platform/win/WCDataObject.h create mode 100644 Source/WebCore/platform/win/WebCoreBundleWin.cpp create mode 100644 Source/WebCore/platform/win/WebCoreBundleWin.h create mode 100644 Source/WebCore/platform/win/WebCoreTextRenderer.cpp create mode 100644 Source/WebCore/platform/win/WebCoreTextRenderer.h create mode 100644 Source/WebCore/platform/win/WheelEventWin.cpp create mode 100644 Source/WebCore/platform/win/WidgetWin.cpp create mode 100644 Source/WebCore/platform/win/Win32Handle.h create mode 100644 Source/WebCore/platform/win/WindowMessageBroadcaster.cpp create mode 100644 Source/WebCore/platform/win/WindowMessageBroadcaster.h create mode 100644 Source/WebCore/platform/win/WindowMessageListener.h create mode 100644 Source/WebCore/platform/win/WindowsTouch.h create mode 100644 Source/WebCore/platform/win/makesafeseh.asm (limited to 'Source') 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 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(); proc->setOriginPrinter( - [this] (PrintStream& out, B3::Origin origin) { + [] (PrintStream& out, B3::Origin origin) { out.print("DFG:", bitwise_cast(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 + * 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 +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace WebCore { + +class MediaPlayerPrivateMediaFoundation : public MediaPlayerPrivateInterface { +public: + explicit MediaPlayerPrivateMediaFoundation(MediaPlayer*); + ~MediaPlayerPrivateMediaFoundation(); + static void registerMediaEngine(MediaEngineRegistrar); + + static void getSupportedTypes(HashSet& 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 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 m_listeners; + Lock m_mutexListeners; + + WeakPtrFactory m_weakPtrFactory; + COMPtr m_mediaSession; + COMPtr m_sourceResolver; + COMPtr m_mediaSource; + COMPtr m_topology; + COMPtr m_sourcePD; + COMPtr 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 sourceSD, COMPtr&); + bool createSourceStreamNode(COMPtr sourceSD, COMPtr&); + + void updateReadyState(); + + COMPtr 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> VideoSampleList; + + class VideoSamplePool { + public: + VideoSamplePool() { } + virtual ~VideoSamplePool() { } + + HRESULT initialize(VideoSampleList& samples); + void clear(); + + HRESULT getSample(COMPtr&); + 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> m_scheduledSamples; + Lock m_lock; + + COMPtr 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 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& 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 m_direct3D9; + COMPtr m_device; + COMPtr m_deviceManager; + COMPtr m_surfaceRepaint; + + COMPtr 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 m_clock; + COMPtr m_mediaEventSink; + COMPtr m_mixer; + COMPtr m_mediaType; + std::unique_ptr 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 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 #include #include -#include #include #include #include @@ -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 cookies = allCookies(); QList::Iterator it = cookies.begin(); QList::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()); } 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& 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 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 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 #include -#include #include #include @@ -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 +#include +#include + +#if USE(CF) +#include +#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 + +#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 +#include +#include + +#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 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 COMPtr(QueryTag, const COMPtr& 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 COMPtr& operator=(const COMPtr&); + + void query(IUnknown* ptr) { adoptRef(copyQueryInterfaceRef(ptr)); } + template void query(const COMPtr& ptr) { query(ptr.get()); } + + void create(const IID& clsid) { adoptRef(createInstance(clsid)); } + + template HRESULT copyRefTo(U**); + void adoptRef(T*); + +private: + static T* copyQueryInterfaceRef(IUnknown*); + static T* createInstance(const IID& clsid); + static T* hashTableDeletedValue() { return reinterpret_cast(-1); } + + T* m_ptr; +}; + +template inline COMPtr adoptCOM(T *ptr) +{ + return COMPtr(AdoptCOM, ptr); +} + +template inline void COMPtr::clear() +{ + if (T* ptr = m_ptr) { + m_ptr = 0; + ptr->Release(); + } +} + +template inline T* COMPtr::leakRef() +{ + T* ptr = m_ptr; + m_ptr = 0; + return ptr; +} + +template inline T* COMPtr::createInstance(const IID& clsid) +{ + T* result; + if (FAILED(CoCreateInstance(clsid, 0, CLSCTX_ALL, __uuidof(result), reinterpret_cast(&result)))) + return 0; + return result; +} + +template inline T* COMPtr::copyQueryInterfaceRef(IUnknown* ptr) +{ + if (!ptr) + return 0; + T* result; + if (FAILED(ptr->QueryInterface(&result))) + return 0; + return result; +} + +template template inline HRESULT COMPtr::copyRefTo(U** ptr) +{ + if (!ptr) + return E_POINTER; + *ptr = m_ptr; + if (m_ptr) + m_ptr->AddRef(); + return S_OK; +} + +template inline void COMPtr::adoptRef(T *ptr) +{ + if (m_ptr) + m_ptr->Release(); + m_ptr = ptr; +} + +template inline COMPtr& COMPtr::operator=(const COMPtr& o) +{ + T* optr = o.get(); + if (optr) + optr->AddRef(); + T* ptr = m_ptr; + m_ptr = optr; + if (ptr) + ptr->Release(); + return *this; +} + +template template inline COMPtr& COMPtr::operator=(const COMPtr& o) +{ + T* optr = o.get(); + if (optr) + optr->AddRef(); + T* ptr = m_ptr; + m_ptr = optr; + if (ptr) + ptr->Release(); + return *this; +} + +template inline COMPtr& COMPtr::operator=(T* optr) +{ + if (optr) + optr->AddRef(); + T* ptr = m_ptr; + m_ptr = optr; + if (ptr) + ptr->Release(); + return *this; +} + +template inline bool operator==(const COMPtr& a, const COMPtr& b) +{ + return a.get() == b.get(); +} + +template inline bool operator==(const COMPtr& a, U* b) +{ + return a.get() == b; +} + +template inline bool operator==(T* a, const COMPtr& b) +{ + return a == b.get(); +} + +template inline bool operator!=(const COMPtr& a, const COMPtr& b) +{ + return a.get() != b.get(); +} + +template inline bool operator!=(const COMPtr& a, U* b) +{ + return a.get() != b; +} + +template inline bool operator!=(T* a, const COMPtr& b) +{ + return a != b.get(); +} + +namespace WTF { + +template struct IsSmartPtr> { + static const bool value = true; +}; + +template struct HashTraits > : SimpleClassHashTraits> { + static P* emptyValue() { return nullptr; } + + typedef P* PeekType; + static PeekType peek(const COMPtr

& value) { return value.get(); } + static PeekType peek(P* value) { return value; } +}; + +template struct DefaultHash> { + typedef PtrHash> 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 +#include +#include // for INTERNET_MAX_URL_LENGTH +#include +#include +#include + + +#if USE(CF) +#include +#include +#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 cfURL = adoptCF(CFURLCreateWithFileSystemPath(0, path, kCFURLWindowsPathStyle, false)); + if (!cfURL) + return false; + + url = CFURLGetString(cfURL.get()); + + // Work around , 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(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(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(GlobalLock(vm)); + StringView(str).getCharactersWithUpconvert(buffer); + buffer[str.length()] = 0; + GlobalUnlock(vm); + return vm; +} + +HGLOBAL createGlobalData(const Vector& vector) +{ + HGLOBAL vm = ::GlobalAlloc(GPTR, vector.size() + 1); + if (!vm) + return 0; + char* buffer = static_cast(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(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& vector, const char* string) +{ + vector.append(string, strlen(string)); +} + +static void append(Vector& vector, const CString& string) +{ + vector.append(string.data(), string.length()); +} + +// Find the markup between "" and "", accounting for browser quirks. +static String extractMarkupFromCFHTML(const String& cfhtml) +{ + unsigned markupStart = 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& 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 = "\n\n\n"; + const char* endMarkup = "\n\n\n"; + + 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(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(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(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(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(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(GlobalLock(store.hGlobal)); + if (data && data[0] && (PathFileExists(data) || PathIsUNC(data))) { + RetainPtr 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(GlobalLock(store.hGlobal)); + if (data && data[0] && (PathFileExistsA(data) || PathIsUNCA(data))) { + RetainPtr 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 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(GlobalLock(store.hGlobal)); + text = String(data); + GlobalUnlock(store.hGlobal); + ReleaseStgMedium(&store); + } else if (SUCCEEDED(dataObject->GetData(plainTextFormat(), &store))) { + // ASCII text + char* data = static_cast(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(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 fragmentFromFilenames(Document*, const IDataObject*) +{ + // FIXME: We should be able to create fragments from files + return 0; +} + +PassRefPtr 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 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 fragmentFromHTML(Document* doc, IDataObject* data) +{ + if (!doc || !data) + return 0; + + String cfhtml = getFullCFHTML(data); + if (!cfhtml.isEmpty()) { + if (RefPtr 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 fragmentFromHTML(Document* document, const DragDataMap* data) +{ + if (!document || !data || data->isEmpty()) + return 0; + + String stringData; + if (getDataMapItem(data, htmlFormat(), stringData)) { + if (RefPtr 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&); +typedef void (*SetStringFunction)(IDataObject*, FORMATETC*, const Vector&); + +struct ClipboardDataItem { + GetStringFunction getString; + SetStringFunction setString; + FORMATETC* format; + + ClipboardDataItem(FORMATETC* format, GetStringFunction getString, SetStringFunction setString): format(format), getString(getString), setString(setString) { } +}; + +typedef HashMap ClipboardFormatMap; + +// Getter functions. + +template void getStringData(IDataObject* data, FORMATETC* format, Vector& dataStrings) +{ + STGMEDIUM store; + if (FAILED(data->GetData(format, &store))) + return; + dataStrings.append(String(static_cast(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T))); + GlobalUnlock(store.hGlobal); + ReleaseStgMedium(&store); +} + +void getUtf8Data(IDataObject* data, FORMATETC* format, Vector& dataStrings) +{ + STGMEDIUM store; + if (FAILED(data->GetData(format, &store))) + return; + dataStrings.append(String(UTF8Encoding().decode(static_cast(GlobalLock(store.hGlobal)), GlobalSize(store.hGlobal)))); + GlobalUnlock(store.hGlobal); + ReleaseStgMedium(&store); +} + +#if USE(CF) +void getCFData(IDataObject* data, FORMATETC* format, Vector& dataStrings) +{ + STGMEDIUM store; + if (FAILED(data->GetData(format, &store))) + return; + + HDROP hdrop = reinterpret_cast(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(filename)); + } + + GlobalUnlock(store.hGlobal); + ReleaseStgMedium(&store); +} +#endif + +// Setter functions. + +void setUCharData(IDataObject* data, FORMATETC* format, const Vector& 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& 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(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& 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(GlobalLock(medium.hGlobal)); + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = TRUE; + String filename = dataStrings.first(); + wcscpy(reinterpret_cast(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, setUCharData)); + formatMap.add(plainTextFormat()->cfFormat, new ClipboardDataItem(plainTextFormat(), getStringData, setUtf8Data)); + formatMap.add(plainTextWFormat()->cfFormat, new ClipboardDataItem(plainTextWFormat(), getStringData, setUCharData)); +#if USE(CF) + formatMap.add(cfHDropFormat()->cfFormat, new ClipboardDataItem(cfHDropFormat(), getCFData, setCFData)); +#endif + formatMap.add(filenameFormat()->cfFormat, new ClipboardDataItem(filenameFormat(), getStringData, setUtf8Data)); + formatMap.add(filenameWFormat()->cfFormat, new ClipboardDataItem(filenameWFormat(), getStringData, setUCharData)); + formatMap.add(urlFormat()->cfFormat, new ClipboardDataItem(urlFormat(), getStringData, setUtf8Data)); + formatMap.add(urlWFormat()->cfFormat, new ClipboardDataItem(urlWFormat(), getStringData, setUCharData)); + } + return formatMap; +} + +void getClipboardData(IDataObject* dataObject, FORMATETC* format, Vector& 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& 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 +#include + +namespace WebCore { + +class Document; +class DocumentFragment; +class URL; + +HGLOBAL createGlobalData(const String&); +HGLOBAL createGlobalData(const Vector&); +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& result); + +void replaceNewlinesWithWindowsStyleNewlines(String&); +void replaceNBSPWithSpace(String&); + +bool containsFilenames(const IDataObject*); +bool containsFilenames(const DragDataMap*); +bool containsHTML(IDataObject*); +bool containsHTML(const DragDataMap*); + +PassRefPtr fragmentFromFilenames(Document*, const IDataObject*); +PassRefPtr fragmentFromFilenames(Document*, const DragDataMap*); +PassRefPtr fragmentFromHTML(Document*, IDataObject*); +PassRefPtr fragmentFromHTML(Document*, const DragDataMap*); +PassRefPtr 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& dataStrings); +void setClipboardData(IDataObject*, UINT format, const Vector& 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 + +#include + +#define ALPHA_CURSORS + +namespace WebCore { + +static PassRefPtr createSharedCursor(Image* img, const IntPoint& hotSpot) +{ + RefPtr 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 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 loadSharedCursor(HINSTANCE hInstance, LPCWSTR lpCursorName) +{ + return SharedCursor::create(::LoadCursorW(hInstance, lpCursorName)); +} + +static PassRefPtr loadCursorByName(char* name, int x, int y) +{ + IntPoint hotSpot(x, y); + RefPtr 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 + m_platformCursor = loadSharedCursor(0, IDC_SIZEWE); + break; + case Cursor::RowResize: + // FIXME: Windows does not have a standard row resize cursor + 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 + +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 + +// See and +// 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(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(convertPotentialRVAToAddress(m_descriptor->rvaDLLName)); +} + +ImportedFunctionsEnumerator DelayLoadedModulesEnumerator::functionsEnumerator() const +{ + ASSERT(!isAtEnd()); + + const IMAGE_THUNK_DATA* importNameTable = static_cast(convertPotentialRVAToAddress(m_descriptor->rvaINT)); + const IMAGE_THUNK_DATA* importAddressTable = static_cast(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(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 +#include +#include +#include +#include +#include +#include +#include + +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 itr; + + if (FAILED(m_platformDragData->EnumFormatEtc(DATADIR_GET, &itr)) || !itr) + return m_dragDataMap; + + FORMATETC dataFormat; + while (itr->Next(1, &dataFormat, 0) == S_OK) { + Vector 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(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& 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(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(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 +#include +#include + +#include + +namespace WebCore { + +void deallocContext(CGContextRef target) +{ + CGContextRelease(target); +} + +GDIObject 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(); + + *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 + if (!imageRef) + return 0; + + GDIObject hbmp; + auto image = adoptGDIObject(imageRef); + + IntSize srcSize = dragImageSize(image.get()); + IntSize dstSize(static_cast(srcSize.width() * scale.width()), static_cast(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 +#include +#include +#include + +namespace WebCore { + +void deallocContext(PlatformContextCairo* target) +{ + delete target; +} + +GDIObject 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(); + + 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 + if (!imageRef) + return 0; + + GDIObject hbmp; + auto image = adoptGDIObject(imageRef); + + IntSize srcSize = dragImageSize(image.get()); + IntSize dstSize(static_cast(srcSize.width() * scale.width()), static_cast(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 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 +#include + +#include + +namespace WebCore { + +GDIObject 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(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 + +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 +#include +#include +#include + +#include +#include +#include + +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(std::numeric_limits::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(std::numeric_limits::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 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(bundleExecutable); + } +#endif + + return name; +} + +static String storageDirectory(DWORD pathIdentifier) +{ + Vector 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 directories; + + HashMap::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(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(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 listDirectory(const String& directory, const String& filter) +{ + Vector entries; + + PathWalker walker(directory, filter); + if (!walker.isValid()) + return entries; + + do { + if (walker.data().dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + + entries.append(directory + "\\" + reinterpret_cast(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 + +#include + +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 + +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 + +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 +#include + +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 and +// 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(m_image.convertRVAToAddress(m_nameTableEntry->u1.AddressOfData)); + return reinterpret_cast(importByName->Name); +} + +const void* const* ImportedFunctionsEnumerator::addressOfCurrentFunctionPointer() const +{ + ASSERT(m_addressTableEntry); + COMPILE_ASSERT(sizeof(void*) == sizeof(m_addressTableEntry->u1.Function), FunctionAddressSizeMatchesPointerSize); + return reinterpret_cast(&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 and +// 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(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(m_image.convertRVAToAddress(m_descriptor->Name)); +} + +ImportedFunctionsEnumerator ImportedModulesEnumerator::functionsEnumerator() const +{ + ASSERT(m_descriptor); + + const IMAGE_THUNK_DATA* importNameTable = static_cast(m_image.convertRVAToAddress(m_descriptor->OriginalFirstThunk)); + const IMAGE_THUNK_DATA* importAddressTable = static_cast(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 +#include + +#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 +#include +#include + +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 platformUserPreferredLanguages() +{ + Vector 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 +#include +#include +#include +#include + +#if USE(CF) +#include "WebCoreBundleWin.h" +#include +#include +#endif + +namespace WebCore { + +String localizedString(const char* key) +{ + ASSERT(isMainThread()); + +#if USE(CF) + static CFStringRef notFound = CFSTR("localized string not found"); + + RetainPtr keyString = adoptCF(CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingUTF8, kCFAllocatorNull)); + RetainPtr 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 +#include +#include + +namespace WebCore { + +static char * const loggingEnvironmentVariable = "WebCoreLogging"; + +String logLevelString() +{ + DWORD length = GetEnvironmentVariableA(loggingEnvironmentVariable, 0, 0); + if (!length) + return emptyString(); + + auto buffer = std::make_unique(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 +#include +#include +#include + +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 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 +#include +#include + +#include + +// 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(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 +#include +#include +#include + +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(&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& memCheckTimer() +{ + static NeverDestroyed> memCheckTimer; + return memCheckTimer; +} + +void MemoryPressureHandler::install() +{ + m_installed = true; + memCheckTimer() = std::make_unique(*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 and +// 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(m_module); + if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) + return; + + const IMAGE_NT_HEADERS* ntHeaders = static_cast(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(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 + +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 + * + * 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 +#include +#include +#include + +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::createForCopyAndPaste() +{ + auto pasteboard = std::make_unique(); + COMPtr clipboardData; + if (!SUCCEEDED(OleGetClipboard(&clipboardData))) + clipboardData = 0; + pasteboard->setExternalDataObject(clipboardData.get()); + return pasteboard; +} + +std::unique_ptr Pasteboard::createPrivate() +{ + // Windows has no "Private pasteboard" concept. + return createForCopyAndPaste(); +} + +#if ENABLE(DRAG_SUPPORT) +std::unique_ptr Pasteboard::createForDragAndDrop() +{ + COMPtr dataObject; + WCDataObject::createInstance(&dataObject); + return std::make_unique(dataObject.get()); +} + +// static +std::unique_ptr Pasteboard::createForDragAndDrop(const DragData& dragData) +{ + if (dragData.platformData()) + return std::make_unique(dragData.platformData()); + // FIXME: Should add a const overload of dragDataMap so we don't need a const_cast here. + return std::make_unique(const_cast(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 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& 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 Pasteboard::types() +{ + ListHashSet results; + + if (!m_dataObject && m_dragDataMap.isEmpty()) + return Vector(); + + if (m_dataObject) { + COMPtr itr; + + if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr))) + return Vector(); + + if (!itr) + return Vector(); + + 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 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 Pasteboard::readFilenames() +{ + Vector fileNames; + +#if USE(CF) + if (m_dataObject) { + STGMEDIUM medium; + if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium))) + return fileNames; + + HDROP hdrop = reinterpret_cast(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 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 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 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(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(fsPathMaxLengthExcludingExtension, lastComponent.length()); + StringView(lastComponent).substring(0, len).getCharactersWithUpconvert(fsPathBuffer); + } else { + len = std::min(fsPathMaxLengthExcludingExtension, url.length()); + StringView(url).substring(0, len).getCharactersWithUpconvert(fsPathBuffer); + } + fsPathBuffer[len] = 0; + pathRemoveBadFSCharacters(fsPathBuffer, len); + } + + if (!extension) + return String(static_cast(fsPathBuffer)); + + if (!isLink && usedURL) { + PathRenameExtension(fsPathBuffer, extension); + return String(static_cast(fsPathBuffer)); + } + + return makeString(static_cast(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(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(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(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 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(element.renderer())) + return; + + auto& renderer = downcast(*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(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(GlobalLock(cbData)); + GlobalUnlock(cbData); + ::CloseClipboard(); + return; + } + ::CloseClipboard(); + } +} + +PassRefPtr 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(GlobalLock(cbData)), dataSize)); + GlobalUnlock(cbData); + ::CloseClipboard(); + + RefPtr 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(GlobalLock(cbData)); + String str(buffer); + GlobalUnlock(cbData); + ::CloseClipboard(); + RefPtr 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(GlobalLock(cbData)); + String str(buffer); + GlobalUnlock(cbData); + ::CloseClipboard(); + RefPtr 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(renderer)) + return nullptr; + + auto* image = downcast(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(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& 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 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 + +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 +#include + +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 +#include +#include +#include +#include + +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 + +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 . + 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 + +#include +#include + +#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 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(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 +String signedPublicKeyAndChallengeString(unsigned, const String&, const URL&) { notImplemented(); return String(); } +void getSupportedKeySizes(Vector&) { 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 + +namespace WebCore { + +class WCEnumFormatEtc : public IEnumFORMATETC +{ +public: + WCEnumFormatEtc(const Vector& formats); + WCEnumFormatEtc(const Vector>& 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 m_formats; + size_t m_current { 0 }; + long m_ref { 1 }; +}; + +WCEnumFormatEtc::WCEnumFormatEtc(const Vector& formats) +{ + for (const auto& format : formats) + m_formats.append(format); +} + +WCEnumFormatEtc::WCEnumFormatEtc(const Vector>& 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(); + std::unique_ptr 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 +#include +#include +#include + +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> m_formats; + Vector> 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 +#include +#include + +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 dllPath = adoptCF(CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(dllPathBuffer), length, kCFAllocatorNull)); + RetainPtr dllURL = adoptCF(CFURLCreateWithFileSystemPath(0, dllPath.get(), kCFURLWindowsPathStyle, false)); + RetainPtr dllDirectoryURL = adoptCF(CFURLCreateCopyDeletingLastPathComponent(0, dllURL.get())); + RetainPtr 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(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 + +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 +#include + +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(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(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(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 +#include + +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 + * + * 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 +#include +#include + +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 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(SetWindowLongPtr(m_subclassedWindow, GWLP_WNDPROC, reinterpret_cast(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(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 +#include +#include + +namespace WebCore { + + class WindowMessageListener; + + class WindowMessageBroadcaster { + WTF_MAKE_NONCOPYABLE(WindowMessageBroadcaster); + public: + static void addListener(HWND, WindowMessageListener*); + static void removeListener(HWND, WindowMessageListener*); + + private: + typedef HashSet 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 + +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 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 FrameLoaderClientQt::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const URL& url, const Vector& paramNames, const Vector& 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 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("

hello world

"); 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) -- cgit v1.2.1