diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:15 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:15 -0800 |
commit | 1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353 (patch) | |
tree | 4457a7306ea5acb43fe05bfe0973b1f7faf97ba2 /WebCore/platform/win | |
parent | 9364f22aed35e1a1e9d07c121510f80be3ab0502 (diff) | |
download | external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.zip external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.gz external_webkit-1cbdecfa9fc428ac2d8aca0fa91c9580b3d57353.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'WebCore/platform/win')
40 files changed, 1375 insertions, 2680 deletions
diff --git a/WebCore/platform/win/BString.cpp b/WebCore/platform/win/BString.cpp index 6228dab..618ecf3 100644 --- a/WebCore/platform/win/BString.cpp +++ b/WebCore/platform/win/BString.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * 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 @@ -27,7 +27,7 @@ #include "BString.h" #include "AtomicString.h" -#include "DeprecatedString.h" +#include "KURL.h" #include "PlatformString.h" #include <tchar.h> #include <windows.h> @@ -36,6 +36,8 @@ #include <CoreFoundation/CoreFoundation.h> #endif +using namespace JSC; + namespace WebCore { BString::BString() @@ -67,12 +69,12 @@ BString::BString(const String& s) m_bstr = SysAllocStringLen(s.characters(), s.length()); } -BString::BString(const DeprecatedString& s) +BString::BString(const KURL& url) { - if (s.isNull()) + if (url.isNull()) m_bstr = 0; else - m_bstr = SysAllocStringLen(String(s).characters(), s.length()); + m_bstr = SysAllocStringLen(url.string().characters(), url.string().length()); } BString::BString(const AtomicString& s) @@ -83,6 +85,14 @@ BString::BString(const AtomicString& s) m_bstr = SysAllocStringLen(s.characters(), s.length()); } +BString::BString(const UString& s) +{ + if (s.isNull()) + m_bstr = 0; + else + m_bstr = SysAllocStringLen(s.data(), s.size()); +} + #if PLATFORM(CF) BString::BString(CFStringRef cfstr) : m_bstr(0) diff --git a/WebCore/platform/win/BString.h b/WebCore/platform/win/BString.h index 5f1d75d..c32a49d 100644 --- a/WebCore/platform/win/BString.h +++ b/WebCore/platform/win/BString.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * 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 @@ -32,10 +32,14 @@ typedef const struct __CFString * CFStringRef; typedef wchar_t* BSTR; +namespace JSC { + class UString; +} + namespace WebCore { class AtomicString; - class DeprecatedString; + class KURL; class String; class BString { @@ -44,8 +48,9 @@ namespace WebCore { BString(const wchar_t*); BString(const wchar_t*, size_t length); BString(const String&); - BString(const DeprecatedString&); BString(const AtomicString&); + BString(const KURL&); + BString(const JSC::UString&); #if PLATFORM(CF) BString(CFStringRef); #endif diff --git a/WebCore/platform/win/COMPtr.h b/WebCore/platform/win/COMPtr.h index 4fb6fbb..784495a 100644 --- a/WebCore/platform/win/COMPtr.h +++ b/WebCore/platform/win/COMPtr.h @@ -49,10 +49,14 @@ public: COMPtr(AdoptCOMTag, T* ptr) : m_ptr(ptr) { } COMPtr(const COMPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->AddRef(); } - inline COMPtr(QueryTag, IUnknown* ptr) : m_ptr(copyQueryInterfaceRef(ptr)) { } - template <typename U> inline COMPtr(QueryTag, const COMPtr<U>& ptr) : m_ptr(copyQueryInterfaceRef(ptr.get())) { } + COMPtr(QueryTag, IUnknown* ptr) : m_ptr(copyQueryInterfaceRef(ptr)) { } + template <typename U> COMPtr(QueryTag, const COMPtr<U>& ptr) : m_ptr(copyQueryInterfaceRef(ptr.get())) { } - inline COMPtr(CreateTag, const IID& clsid) : m_ptr(createInstance(clsid)) { } + 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(); } @@ -75,7 +79,7 @@ public: template <typename U> COMPtr& operator=(const COMPtr<U>&); void query(IUnknown* ptr) { adoptRef(copyQueryInterfaceRef(ptr)); } - template <typename U> inline void query(const COMPtr<U>& ptr) { query(ptr.get()); } + template <typename U> void query(const COMPtr<U>& ptr) { query(ptr.get()); } void create(const IID& clsid) { adoptRef(createInstance(clsid)); } @@ -85,6 +89,7 @@ public: private: static T* copyQueryInterfaceRef(IUnknown*); static T* createInstance(const IID& clsid); + static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } T* m_ptr; }; @@ -190,41 +195,23 @@ template <typename T, typename U> inline bool operator!=(T* a, const COMPtr<U>& } namespace WTF { + template<typename P> struct HashTraits<COMPtr<P> > : GenericHashTraits<COMPtr<P> > { - typedef HashTraits<typename IntTypes<sizeof(P*)>::SignedType> StorageTraits; - typedef typename StorageTraits::TraitType StorageType; static const bool emptyValueIsZero = true; - static const bool needsRef = true; - - typedef union { - P* m_p; - StorageType m_s; - } UnionType; - - static void ref(const StorageType& s) - { - if (const P* p = reinterpret_cast<const UnionType*>(&s)->m_p) - const_cast<P*>(p)->AddRef(); - } - static void deref(const StorageType& s) - { - if (const P* p = reinterpret_cast<const UnionType*>(&s)->m_p) - const_cast<P*>(p)->Release(); - } + static void constructDeletedValue(COMPtr<P>& slot) { slot.releaseRef(); *&slot = reinterpret_cast<P*>(-1); } + static bool isDeletedValue(const COMPtr<P>& value) { return value == reinterpret_cast<P*>(-1); } }; - template<typename P> struct HashKeyStorageTraits<PtrHash<COMPtr<P> >, HashTraits<COMPtr<P> > > { - typedef typename IntTypes<sizeof(P*)>::SignedType IntType; - typedef IntHash<IntType> Hash; - typedef HashTraits<IntType> Traits; + template<typename P> struct PtrHash<COMPtr<P> > : PtrHash<P*> { + using PtrHash<P*>::hash; + static unsigned hash(const COMPtr<P>& key) { return hash(key.get()); } + using PtrHash<P*>::equal; + static bool equal(const COMPtr<P>& a, const COMPtr<P>& b) { return a == b; } + static bool equal(P* a, const COMPtr<P>& b) { return a == b; } + static bool equal(const COMPtr<P>& a, P* b) { return a == b; } }; template<typename P> struct DefaultHash<COMPtr<P> > { typedef PtrHash<COMPtr<P> > Hash; }; - - template<typename P> struct PtrHash<COMPtr<P> > { - static unsigned hash(const COMPtr<P>& key) { return PtrHash<P*>::hash(key.get()); } - static bool equal(const COMPtr<P>& a, const COMPtr<P>& b) { return a == b; } - }; } #endif diff --git a/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/WebCore/platform/win/ClipboardUtilitiesWin.cpp index 066e235..3762a1a 100644 --- a/WebCore/platform/win/ClipboardUtilitiesWin.cpp +++ b/WebCore/platform/win/ClipboardUtilitiesWin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * 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 @@ -26,12 +26,12 @@ #include "config.h" #include "ClipboardUtilitiesWin.h" -#include "KURL.h" #include "CString.h" #include "DocumentFragment.h" -#include "markup.h" +#include "KURL.h" #include "PlatformString.h" #include "TextEncoding.h" +#include "markup.h" #include <CoreFoundation/CoreFoundation.h> #include <wtf/RetainPtr.h> #include <shlwapi.h> @@ -120,93 +120,103 @@ HGLOBAL createGlobalData(const KURL& url, const String& title) return cbData; } -HGLOBAL createGlobalData(String str) -{ - SIZE_T size = (str.length() + 1) * sizeof(UChar); - HGLOBAL cbData = ::GlobalAlloc(GPTR, size); - if (cbData) { - void* buffer = ::GlobalLock(cbData); - memcpy(buffer, str.charactersWithNullTermination(), size); - ::GlobalUnlock(cbData); - } - return cbData; +HGLOBAL createGlobalData(const String& str) +{ + HGLOBAL globalData = ::GlobalAlloc(GPTR, (str.length() + 1) * sizeof(UChar)); + if (!globalData) + return 0; + UChar* buffer = static_cast<UChar*>(::GlobalLock(globalData)); + memcpy(buffer, str.characters(), str.length() * sizeof(UChar)); + buffer[str.length()] = 0; + ::GlobalUnlock(globalData); + return globalData; } -HGLOBAL createGlobalData(CString str) +HGLOBAL createGlobalData(const Vector<char>& vector) { - SIZE_T size = str.length() * sizeof(char); - HGLOBAL cbData = ::GlobalAlloc(GPTR, size + 1); - if (cbData) { - char* buffer = static_cast<char*>(::GlobalLock(cbData)); - memcpy(buffer, str.data(), size); - buffer[size] = 0; - ::GlobalUnlock(cbData); - } - return cbData; + HGLOBAL globalData = ::GlobalAlloc(GPTR, vector.size() + 1); + if (!globalData) + return 0; + char* buffer = static_cast<char*>(::GlobalLock(globalData)); + memcpy(buffer, vector.data(), vector.size()); + buffer[vector.size()] = 0; + ::GlobalUnlock(globalData); + return globalData; +} + +static void append(Vector<char>& vector, const char* string) +{ + vector.append(string, strlen(string)); +} + +static void append(Vector<char>& vector, const CString& string) +{ + vector.append(string.data(), string.length()); } // Documentation for the CF_HTML format is available at http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp -DeprecatedCString markupToCF_HTML(const String& markup, const String& srcURL) +void markupToCF_HTML(const String& markup, const String& srcURL, Vector<char>& result) { - if (!markup.length()) - return DeprecatedCString(); + if (markup.isEmpty()) + return; - DeprecatedCString cf_html ("Version:0.9"); - DeprecatedCString startHTML ("\nStartHTML:"); - DeprecatedCString endHTML ("\nEndHTML:"); - DeprecatedCString startFragment ("\nStartFragment:"); - DeprecatedCString endFragment ("\nEndFragment:"); - DeprecatedCString sourceURL ("\nSourceURL:"); + #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) - bool shouldFillSourceURL = !srcURL.isEmpty() && (srcURL != "about:blank"); - if (shouldFillSourceURL) - sourceURL.append(srcURL.utf8().data()); + 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:"; - DeprecatedCString startMarkup ("\n<HTML>\n<BODY>\n<!--StartFragment-->\n"); - DeprecatedCString endMarkup ("\n<!--EndFragment-->\n</BODY>\n</HTML>"); + const char* startMarkup = "<HTML>\n<BODY>\n<!--StartFragment-->\n"; + const char* endMarkup = "\n<!--EndFragment-->\n</BODY>\n</HTML>"; - // calculate offsets - const unsigned UINT_MAXdigits = 10; // number of digits in UINT_MAX in base 10 - unsigned startHTMLOffset = cf_html.length() + startHTML.length() + endHTML.length() + startFragment.length() + endFragment.length() + (shouldFillSourceURL ? sourceURL.length() : 0) + (4*UINT_MAXdigits); - unsigned startFragmentOffset = startHTMLOffset + startMarkup.length(); + 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 + endMarkup.length(); - - // fill in needed data - startHTML.append(String::format("%010u", startHTMLOffset).deprecatedString().utf8()); - endHTML.append(String::format("%010u", endHTMLOffset).deprecatedString().utf8()); - startFragment.append(String::format("%010u", startFragmentOffset).deprecatedString().utf8()); - endFragment.append(String::format("%010u", endFragmentOffset).deprecatedString().utf8()); - startMarkup.append(markupUTF8.data()); - - // create full cf_html string from the fragments - cf_html.append(startHTML); - cf_html.append(endHTML); - cf_html.append(startFragment); - cf_html.append(endFragment); - if (shouldFillSourceURL) - cf_html.append(sourceURL); - cf_html.append(startMarkup); - cf_html.append(endMarkup); - - return cf_html; + unsigned endHTMLOffset = endFragmentOffset + strlen(endMarkup); + + append(result, String::format(header, startHTMLOffset, endHTMLOffset, startFragmentOffset, endFragmentOffset).utf8()); + 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 } String urlToMarkup(const KURL& url, const String& title) { - String markup("<a href=\""); - markup.append(url.string()); - markup.append("\">"); - markup.append(title); - markup.append("</a>"); - return markup; + Vector<UChar> markup; + append(markup, "<a href=\""); + append(markup, url.string()); + append(markup, "\">"); + append(markup, title); + append(markup, "</a>"); + return String::adopt(markup); } void replaceNewlinesWithWindowsStyleNewlines(String& str) { static const UChar Newline = '\n'; - static const String WindowsNewline("\r\n"); + static const char* const WindowsNewline("\r\n"); str.replace(Newline, WindowsNewline); } @@ -400,7 +410,7 @@ PassRefPtr<DocumentFragment> fragmentFromCF_HTML(Document* doc, const String& cf unsigned fragmentEnd = cf_html.reverseFind('<', tagEnd); String markup = cf_html.substring(fragmentStart, fragmentEnd - fragmentStart).stripWhiteSpace(); - return createFragmentFromMarkup(doc, markup, srcURL).releaseRef(); + return createFragmentFromMarkup(doc, markup, srcURL); } diff --git a/WebCore/platform/win/ClipboardUtilitiesWin.h b/WebCore/platform/win/ClipboardUtilitiesWin.h index 49898ea..a92a4bf 100644 --- a/WebCore/platform/win/ClipboardUtilitiesWin.h +++ b/WebCore/platform/win/ClipboardUtilitiesWin.h @@ -31,14 +31,12 @@ namespace WebCore { -class CString; -class DeprecatedCString; class Document; class KURL; class String; -HGLOBAL createGlobalData(String str); -HGLOBAL createGlobalData(CString str); +HGLOBAL createGlobalData(const String&); +HGLOBAL createGlobalData(const Vector<char>&); HGLOBAL createGlobalData(const KURL& url, const String& title); FORMATETC* urlWFormat(); @@ -51,21 +49,21 @@ FORMATETC* htmlFormat(); FORMATETC* cfHDropFormat(); FORMATETC* smartPasteFormat(); -DeprecatedCString markupToCF_HTML(const String& markup, const String& srcURL); +void markupToCF_HTML(const String& markup, const String& srcURL, Vector<char>& result); String urlToMarkup(const KURL& url, const String& title); -void replaceNewlinesWithWindowsStyleNewlines(String& str); -void replaceNBSPWithSpace(String& str); +void replaceNewlinesWithWindowsStyleNewlines(String&); +void replaceNBSPWithSpace(String&); bool containsFilenames(const IDataObject*); -bool containsHTML(IDataObject* data); +bool containsHTML(IDataObject*); PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*); -PassRefPtr<DocumentFragment> fragmentFromHTML(Document* doc, IDataObject* data); -PassRefPtr<DocumentFragment> fragmentFromCF_HTML(Document* doc, const String& cf_html); +PassRefPtr<DocumentFragment> fragmentFromHTML(Document*, IDataObject*); +PassRefPtr<DocumentFragment> fragmentFromCF_HTML(Document*, const String& cf_html); -String getURL(IDataObject* dataObject, bool& success, String* title = 0); -String getPlainText(IDataObject* dataObject, bool& success); +String getURL(IDataObject*, bool& success, String* title = 0); +String getPlainText(IDataObject*, bool& success); } // namespace WebCore diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp index fbbbedb..129d881 100644 --- a/WebCore/platform/win/ClipboardWin.cpp +++ b/WebCore/platform/win/ClipboardWin.cpp @@ -26,11 +26,9 @@ #include "config.h" #include "ClipboardWin.h" +#include "CString.h" #include "CachedImage.h" #include "ClipboardUtilitiesWin.h" -#include "csshelper.h" -#include "CString.h" -#include "DeprecatedString.h" #include "Document.h" #include "DragData.h" #include "Editor.h" @@ -42,7 +40,6 @@ #include "HTMLNames.h" #include "Image.h" #include "MIMETypeRegistry.h" -#include "markup.h" #include "Page.h" #include "Pasteboard.h" #include "PlatformMouseEvent.h" @@ -52,12 +49,16 @@ #include "ResourceResponse.h" #include "StringHash.h" #include "WCDataObject.h" +#include "csshelper.h" +#include "markup.h" #include <shlwapi.h> #include <wininet.h> #include <wtf/RefPtr.h> +using namespace std; + namespace WebCore { using namespace HTMLNames; @@ -140,7 +141,7 @@ static String filesystemPathFromUrlOrTitle(const String& url, const String& titl // The filename for any content based drag 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. - KURL kurl(url.deprecatedString()); + KURL kurl(url); String lastComponent; if (!isLink && !(lastComponent = kurl.lastPathComponent()).isEmpty()) { len = min<DWORD>(MAX_PATH, lastComponent.length()); @@ -226,11 +227,10 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share WCHAR filePath[MAX_PATH]; if (url.isLocalFile()) { - DeprecatedString path = url.path(); + String localPath = url.path(); // windows does not enjoy a leading slash on paths - if (path[0] == '/') - path = path.mid(1); - String localPath = path.ascii(); + if (localPath[0] == '/') + localPath = localPath.substring(1); LPCTSTR localPathStr = localPath.charactersWithNullTermination(); if (wcslen(localPathStr) + 1 < MAX_PATH) wcscpy_s(filePath, MAX_PATH, localPathStr); @@ -437,7 +437,9 @@ static bool writeURL(WCDataObject *data, const KURL& url, String title, bool wit success = true; if (withHTML) { - medium.hGlobal = createGlobalData(markupToCF_HTML(urlToMarkup(url, title), "")); + Vector<char> cfhtmlData; + markupToCF_HTML(urlToMarkup(url, title), "", cfhtmlData); + medium.hGlobal = createGlobalData(cfhtmlData); if (medium.hGlobal && FAILED(data->SetData(htmlFormat(), &medium, TRUE))) ::GlobalFree(medium.hGlobal); else @@ -503,7 +505,7 @@ String ClipboardWin::getData(const String& type, bool& success) const return ""; } -bool ClipboardWin::setData(const String &type, const String &data) +bool ClipboardWin::setData(const String& type, const String& data) { // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941> ASSERT(isForDragging()); @@ -513,7 +515,7 @@ bool ClipboardWin::setData(const String &type, const String &data) ClipboardDataType winType = clipboardTypeFromMIMEType(type); if (winType == ClipboardDataTypeURL) - return WebCore::writeURL(m_writableDataObject.get(), data.deprecatedString(), String(), false, true); + return WebCore::writeURL(m_writableDataObject.get(), KURL(data), String(), false, true); if (winType == ClipboardDataTypeText) { STGMEDIUM medium = {0}; @@ -579,10 +581,10 @@ void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint & return; if (m_dragImage) - m_dragImage->deref(this); + m_dragImage->removeClient(this); m_dragImage = image; if (m_dragImage) - m_dragImage->ref(this); + m_dragImage->addClient(this); m_dragLoc = loc; m_dragImageElement = node; @@ -676,7 +678,7 @@ void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, c if (imageURL.isEmpty()) return; - String fullURL = frame->document()->completeURL(parseURL(imageURL)); + String fullURL = frame->document()->completeURL(parseURL(imageURL)).string(); if (fullURL.isEmpty()) return; STGMEDIUM medium = {0}; @@ -684,7 +686,9 @@ void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, c ExceptionCode ec = 0; // Put img tag on the clipboard referencing the image - medium.hGlobal = createGlobalData(markupToCF_HTML(imageToMarkup(fullURL), "")); + Vector<char> data; + markupToCF_HTML(imageToMarkup(fullURL), "", data); + medium.hGlobal = createGlobalData(data); if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE))) ::GlobalFree(medium.hGlobal); } @@ -719,7 +723,10 @@ void ClipboardWin::writeRange(Range* selectedRange, Frame* frame) medium.tymed = TYMED_HGLOBAL; ExceptionCode ec = 0; - medium.hGlobal = createGlobalData(markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), selectedRange->startContainer(ec)->document()->url())); + Vector<char> data; + markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), + selectedRange->startContainer(ec)->document()->url().string(), data); + medium.hGlobal = createGlobalData(data); if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE))) ::GlobalFree(medium.hGlobal); diff --git a/WebCore/platform/win/ClipboardWin.h b/WebCore/platform/win/ClipboardWin.h index 0d6e448..01f7332 100644 --- a/WebCore/platform/win/ClipboardWin.h +++ b/WebCore/platform/win/ClipboardWin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * 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 @@ -26,10 +26,8 @@ #ifndef ClipboardWin_h #define ClipboardWin_h -#include "Clipboard.h" - #include "CachedResourceClient.h" -#include "IntPoint.h" +#include "Clipboard.h" #include "COMPtr.h" struct IDataObject; @@ -43,8 +41,14 @@ namespace WebCore { // State available during IE's events for drag and drop and copy/paste class ClipboardWin : public Clipboard, public CachedResourceClient { public: - ClipboardWin(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy); - ClipboardWin(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy); + static PassRefPtr<ClipboardWin> create(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy) + { + return adoptRef(new ClipboardWin(isForDragging, dataObject, policy)); + } + static PassRefPtr<ClipboardWin> create(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy) + { + return adoptRef(new ClipboardWin(isForDragging, dataObject, policy)); + } ~ClipboardWin(); void clearData(const String& type); @@ -66,9 +70,14 @@ namespace WebCore { virtual bool hasData(); COMPtr<IDataObject> dataObject() { return m_dataObject; } + private: + ClipboardWin(bool isForDragging, IDataObject*, ClipboardAccessPolicy); + ClipboardWin(bool isForDragging, WCDataObject*, ClipboardAccessPolicy); + void resetFromClipboard(); void setDragImage(CachedImage*, Node*, const IntPoint&); + COMPtr<IDataObject> m_dataObject; COMPtr<WCDataObject> m_writableDataObject; Frame* m_frame; diff --git a/WebCore/platform/win/CursorWin.cpp b/WebCore/platform/win/CursorWin.cpp index 1e31617..e91e86b 100644 --- a/WebCore/platform/win/CursorWin.cpp +++ b/WebCore/platform/win/CursorWin.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * 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 @@ -72,7 +72,9 @@ Cursor::Cursor(Image* img, const IntPoint& hotspot) SetBkMode(workingDC, TRANSPARENT); SelectObject(workingDC, hOldBitmap); - OwnPtr<HBITMAP> hMask(CreateBitmap(img->width(), img->height(), 1, 1, NULL)); + Vector<unsigned char, 128> maskBits; + maskBits.fill(0xff, (img->width() + 7) / 8 * img->height()); + OwnPtr<HBITMAP> hMask(CreateBitmap(img->width(), img->height(), 1, 1, maskBits.data())); ICONINFO ii; ii.fIcon = FALSE; @@ -81,7 +83,7 @@ Cursor::Cursor(Image* img, const IntPoint& hotspot) ii.hbmMask = hMask.get(); ii.hbmColor = hCursor.get(); - m_impl = new SharedCursor(CreateIconIndirect(&ii)); + m_impl = SharedCursor::create(CreateIconIndirect(&ii)); } else { // Platform doesn't support alpha blended cursors, so we need // to create the mask manually @@ -116,7 +118,7 @@ Cursor::Cursor(Image* img, const IntPoint& hotspot) icon.yHotspot = hotspot.y(); icon.hbmMask = andMask.get(); icon.hbmColor = xorMask.get(); - m_impl = new SharedCursor(CreateIconIndirect(&icon)); + m_impl = SharedCursor::create(CreateIconIndirect(&icon)); DeleteDC(xorMaskDC); DeleteDC(andMaskDC); @@ -144,7 +146,7 @@ static Cursor loadCursorByName(char* name, int x, int y) { IntPoint hotSpot(x, y); Cursor c; - OwnPtr<Image> cursorImage(Image::loadPlatformResource(name)); + RefPtr<Image> cursorImage(Image::loadPlatformResource(name)); if (cursorImage && !cursorImage->isNull()) c = Cursor(cursorImage.get(), hotSpot); else @@ -154,7 +156,7 @@ static Cursor loadCursorByName(char* name, int x, int y) static PassRefPtr<SharedCursor> loadSharedCursor(HINSTANCE hInstance, LPCTSTR lpCursorName) { - return new SharedCursor(LoadCursor(hInstance, lpCursorName)); + return SharedCursor::create(LoadCursor(hInstance, lpCursorName)); } const Cursor& pointerCursor() @@ -279,6 +281,60 @@ const Cursor& rowResizeCursor() return c; } +const Cursor& middlePanningCursor() +{ + static const Cursor c = loadCursorByName("panIcon", 7, 7); + return c; +} + +const Cursor& eastPanningCursor() +{ + static const Cursor c = loadCursorByName("panEastCursor", 7, 7); + return c; +} + +const Cursor& northPanningCursor() +{ + static const Cursor c = loadCursorByName("panNorthCursor", 7, 7); + return c; +} + +const Cursor& northEastPanningCursor() +{ + static const Cursor c = loadCursorByName("panNorthEastCursor", 7, 7); + return c; +} + +const Cursor& northWestPanningCursor() +{ + static const Cursor c = loadCursorByName("panNorthWestCursor", 7, 7); + return c; +} + +const Cursor& southPanningCursor() +{ + static const Cursor c = loadCursorByName("panSouthCursor", 7, 7); + return c; +} + +const Cursor& southEastPanningCursor() +{ + static const Cursor c = loadCursorByName("panSouthEastCursor", 7, 7); + return c; +} + +const Cursor& southWestPanningCursor() +{ + static const Cursor c = loadCursorByName("panSouthWestCursor", 7, 7); + return c; +} + +const Cursor& westPanningCursor() +{ + static const Cursor c = loadCursorByName("panWestCursor", 7, 7); + return c; +} + const Cursor& moveCursor() { static Cursor c = loadSharedCursor(0, IDC_SIZEALL); @@ -346,4 +402,14 @@ const Cursor& zoomOutCursor() return c; } +const Cursor& grabCursor() +{ + return pointerCursor(); +} + +const Cursor& grabbingCursor() +{ + return pointerCursor(); +} + } diff --git a/WebCore/platform/win/DragDataWin.cpp b/WebCore/platform/win/DragDataWin.cpp index 26f72d6..30487b8 100644 --- a/WebCore/platform/win/DragDataWin.cpp +++ b/WebCore/platform/win/DragDataWin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * 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 @@ -39,9 +39,9 @@ namespace WebCore { -Clipboard* DragData::createClipboard(ClipboardAccessPolicy policy) const +PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const { - return new ClipboardWin(true, m_platformDragData, policy); + return ClipboardWin::create(true, m_platformDragData, policy); } bool DragData::containsURL() const diff --git a/WebCore/platform/win/DragImageCairoWin.cpp b/WebCore/platform/win/DragImageCairoWin.cpp index 1c9973d..5fff64f 100644 --- a/WebCore/platform/win/DragImageCairoWin.cpp +++ b/WebCore/platform/win/DragImageCairoWin.cpp @@ -47,8 +47,7 @@ DragImageRef createDragImageFromImage(Image* img) { notImplemented(); - DragImageRef temp; - return temp; + return 0; } } diff --git a/WebCore/platform/win/EditorWin.cpp b/WebCore/platform/win/EditorWin.cpp index 5738a64..813eb78 100644 --- a/WebCore/platform/win/EditorWin.cpp +++ b/WebCore/platform/win/EditorWin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * 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 @@ -45,7 +45,7 @@ PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy) if (!SUCCEEDED(OleGetClipboard(&clipboardData))) clipboardData = 0; - return new ClipboardWin(false, clipboardData.get(), policy); + return ClipboardWin::create(false, clipboardData.get(), policy); } } // namespace WebCore diff --git a/WebCore/platform/win/EventLoopWin.cpp b/WebCore/platform/win/EventLoopWin.cpp new file mode 100644 index 0000000..aae107d --- /dev/null +++ b/WebCore/platform/win/EventLoopWin.cpp @@ -0,0 +1,43 @@ +/* + * 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" + +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/WebCore/platform/win/FileChooserWin.cpp b/WebCore/platform/win/FileChooserWin.cpp index 905bf92..7d07b5d 100644 --- a/WebCore/platform/win/FileChooserWin.cpp +++ b/WebCore/platform/win/FileChooserWin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * 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 @@ -26,13 +26,7 @@ #include "config.h" #include "FileChooser.h" -#include "Document.h" -#include "FrameView.h" -#include "Icon.h" #include "LocalizedStrings.h" -#include "RenderObject.h" -#include "RenderThemeWin.h" -#include "RenderView.h" #include "StringTruncator.h" #include <shlwapi.h> #include <tchar.h> @@ -40,65 +34,22 @@ namespace WebCore { -FileChooser::FileChooser(FileChooserClient* client, const String& filename) - : m_client(client) - , m_filename(filename) - , m_icon(chooseIcon(filename)) -{ -} - -FileChooser::~FileChooser() -{ -} - -void FileChooser::openFileChooser(Document* document) -{ - FrameView* view = document->view(); - if (!view) - return; - - TCHAR fileBuf[MAX_PATH]; - OPENFILENAME ofn; - - memset(&ofn, 0, sizeof(ofn)); - - // Need to zero out the first char of fileBuf so GetOpenFileName doesn't think it's an initialization string - fileBuf[0] = '\0'; - - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = view->containingWindow(); - String allFiles = allFilesText(); - allFiles.append(TEXT("\0*.*\0\0"), 6); - ofn.lpstrFilter = allFiles.charactersWithNullTermination(); - ofn.lpstrFile = fileBuf; - ofn.nMaxFile = sizeof(fileBuf); - String dialogTitle = uploadFileText(); - ofn.lpstrTitle = dialogTitle.charactersWithNullTermination(); - ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; - - // We need this protector because otherwise we can be deleted if the file upload control is detached while - // we're within the GetOpenFileName call. - RefPtr<FileChooser> protector(this); - - if (GetOpenFileName(&ofn)) - chooseFile(String(fileBuf)); -} - String FileChooser::basenameForWidth(const Font& font, int width) const { if (width <= 0) return String(); String string; - if (m_filename.isEmpty()) + if (m_filenames.isEmpty()) string = fileButtonNoFileSelectedLabel(); - else { - String tmpFilename = m_filename; + else if (m_filenames.size() == 1) { + String tmpFilename = m_filenames[0]; LPTSTR basename = PathFindFileName(tmpFilename.charactersWithNullTermination()); string = String(basename); - } + } else + return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font, false); return StringTruncator::centerTruncate(string, width, font, false); } -}
\ No newline at end of file +} // namespace WebCore diff --git a/WebCore/platform/win/FileSystemWin.cpp b/WebCore/platform/win/FileSystemWin.cpp index f721f3e..5671462 100644 --- a/WebCore/platform/win/FileSystemWin.cpp +++ b/WebCore/platform/win/FileSystemWin.cpp @@ -126,6 +126,17 @@ String homeDirectoryPath() return ""; } +String pathGetFileName(const String& path) +{ + return String(::PathFindFileName(String(path).charactersWithNullTermination())); +} + +String directoryName(const String& path) +{ + notImplemented(); + return String(); +} + static String bundleName() { static bool initialized; @@ -173,25 +184,51 @@ static String cachedStorageDirectory(DWORD pathIdentifier) return directory; } - -CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle) +CString openTemporaryFile(const char*, PlatformFileHandle& handle) { + handle = INVALID_HANDLE_VALUE; + char tempPath[MAX_PATH]; int tempPathLength = ::GetTempPathA(_countof(tempPath), tempPath); if (tempPathLength <= 0 || tempPathLength > _countof(tempPath)) return 0; - char tempFile[MAX_PATH]; - if (::GetTempFileNameA(tempPath, prefix, 0, tempFile) > 0) { - HANDLE tempHandle = ::CreateFileA(tempFile, GENERIC_READ | GENERIC_WRITE, 0, 0, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + HCRYPTPROV hCryptProv = 0; + if (!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + return 0; - if (isHandleValid(tempHandle)) { - handle = tempHandle; - return tempFile; - } + char proposedPath[MAX_PATH]; + while (1) { + char tempFile[] = "XXXXXXXX.tmp"; // Use 8.3 style name (more characters aren't helpful due to 8.3 short file names) + const int randomPartLength = 8; + if (!CryptGenRandom(hCryptProv, randomPartLength, reinterpret_cast<BYTE*>(tempFile))) + break; + + // 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(strlen(tempFile) == sizeof(tempFile) - 1); + + if (!PathCombineA(proposedPath, tempPath, tempFile)) + break; + + // use CREATE_NEW to avoid overwriting an existing file with the same name + handle = CreateFileA(proposedPath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); + if (!isHandleValid(handle) && GetLastError() == ERROR_ALREADY_EXISTS) + continue; + + break; } - return 0; + + CryptReleaseContext(hCryptProv, 0); + + if (!isHandleValid(handle)) + return 0; + + return proposedPath; } void closeFile(PlatformFileHandle& handle) @@ -214,6 +251,12 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length) return -1; return static_cast<int>(bytesWritten); } + +bool unloadModule(PlatformModule module) +{ + return ::FreeLibrary(module); +} + String localUserSpecificStorageDirectory() { return cachedStorageDirectory(CSIDL_LOCAL_APPDATA); @@ -254,4 +297,11 @@ bool safeCreateFile(const String& path, CFDataRef data) return true; } +Vector<String> listDirectory(const String& path, const String& filter) +{ + Vector<String> entries; + notImplemented(); + return entries; +} + } // namespace WebCore diff --git a/WebCore/platform/win/KeyEventWin.cpp b/WebCore/platform/win/KeyEventWin.cpp index c8f3ffa..99dfe44 100644 --- a/WebCore/platform/win/KeyEventWin.cpp +++ b/WebCore/platform/win/KeyEventWin.cpp @@ -193,6 +193,7 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData, , m_keyIdentifier((type == Char) ? String() : keyIdentifierForWindowsKeyCode(code)) , m_autoRepeat(HIWORD(keyData) & KF_REPEAT) , m_windowsVirtualKeyCode((type == RawKeyDown || type == KeyUp) ? code : 0) + , m_nativeVirtualKeyCode(m_windowsVirtualKeyCode) , m_isKeypad(isKeypadEvent(code, keyData, type)) , m_shiftKey(GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT) , m_ctrlKey(GetKeyState(VK_CONTROL) & HIGH_BIT_MASK_SHORT) diff --git a/WebCore/platform/win/MutexWin.cpp b/WebCore/platform/win/MutexWin.cpp deleted file mode 100644 index 41d7fe4..0000000 --- a/WebCore/platform/win/MutexWin.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007 Brent Fulgham - * - * 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 Computer, 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 "Threading.h" - -namespace WebCore { - -Mutex::Mutex() -{ - m_mutex.m_recursionCount = 0; - ::InitializeCriticalSection(&m_mutex.m_internalMutex); -} - -Mutex::~Mutex() -{ - ::DeleteCriticalSection(&m_mutex.m_internalMutex); -} - -void Mutex::lock() -{ - ::EnterCriticalSection(&m_mutex.m_internalMutex); - ++m_mutex.m_recursionCount; -} - -bool Mutex::tryLock() -{ - // This method is modeled after the behavior of pthread_mutex_trylock, - // which will return an error if the lock is already owned by the - // current thread. Since the primitive Win32 'TryEnterCriticalSection' - // treats this as a successful case, it changes the behavior of several - // tests in WebKit that check to see if the current thread already - // owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord) - DWORD result = ::TryEnterCriticalSection(&m_mutex.m_internalMutex); - - if (result != 0) { // We got the lock - // If this thread already had the lock, we must unlock and - // return false so that we mimic the behavior of POSIX's - // pthread_mutex_trylock: - if (m_mutex.m_recursionCount > 0) { - ::LeaveCriticalSection(&m_mutex.m_internalMutex); - return false; - } - - ++m_mutex.m_recursionCount; - return true; - } - - return false; -} - -void Mutex::unlock() -{ - --m_mutex.m_recursionCount; - ::LeaveCriticalSection(&m_mutex.m_internalMutex); -} - -} // namespace WebCore diff --git a/WebCore/platform/win/PasteboardWin.cpp b/WebCore/platform/win/PasteboardWin.cpp index 427c303..506cc7b 100644 --- a/WebCore/platform/win/PasteboardWin.cpp +++ b/WebCore/platform/win/PasteboardWin.cpp @@ -26,11 +26,10 @@ #include "config.h" #include "Pasteboard.h" -#include "ClipboardUtilitiesWin.h" #include "CString.h" -#include "DeprecatedString.h" -#include "DocumentFragment.h" +#include "ClipboardUtilitiesWin.h" #include "Document.h" +#include "DocumentFragment.h" #include "Element.h" #include "Frame.h" #include "HitTestResult.h" @@ -116,7 +115,10 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, // Put CF_HTML format on the pasteboard if (::OpenClipboard(m_owner)) { ExceptionCode ec = 0; - HGLOBAL cbData = createGlobalData(markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), selectedRange->startContainer(ec)->document()->url())); + Vector<char> data; + markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), + selectedRange->startContainer(ec)->document()->url().string(), data); + HGLOBAL cbData = createGlobalData(data); if (!::SetClipboardData(HTMLClipboardFormat, cbData)) ::GlobalFree(cbData); ::CloseClipboard(); @@ -166,7 +168,9 @@ void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame) // write to clipboard in format CF_HTML to be able to paste into contenteditable areas as a link if (::OpenClipboard(m_owner)) { - HGLOBAL cbData = createGlobalData(markupToCF_HTML(urlToMarkup(url, title), "")); + Vector<char> data; + markupToCF_HTML(urlToMarkup(url, title), "", data); + HGLOBAL cbData = createGlobalData(data); if (!::SetClipboardData(HTMLClipboardFormat, cbData)) ::GlobalFree(cbData); ::CloseClipboard(); diff --git a/WebCore/platform/win/PlatformScreenWin.cpp b/WebCore/platform/win/PlatformScreenWin.cpp index 0a47987..56c8139 100644 --- a/WebCore/platform/win/PlatformScreenWin.cpp +++ b/WebCore/platform/win/PlatformScreenWin.cpp @@ -38,7 +38,7 @@ namespace WebCore { // Returns info for the default monitor if widget is NULL static MONITORINFOEX monitorInfoForWidget(Widget* widget) { - HWND window = widget ? widget->containingWindow() : 0; + HWND window = widget ? widget->root()->hostWindow()->platformWindow() : 0; HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY); MONITORINFOEX monitorInfo; diff --git a/WebCore/platform/win/PlatformScrollBar.h b/WebCore/platform/win/PlatformScrollBar.h index 43f2f95..c84616a 100644 --- a/WebCore/platform/win/PlatformScrollBar.h +++ b/WebCore/platform/win/PlatformScrollBar.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 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 @@ -26,86 +26,22 @@ #ifndef PlatformScrollbar_h #define PlatformScrollbar_h -#include "Widget.h" -#include "ScrollBar.h" +#include "Scrollbar.h" #include "Timer.h" +#include <wtf/PassRefPtr.h> typedef struct HDC__* HDC; namespace WebCore { -enum ScrollbarPart { NoPart, BackButtonPart, BackTrackPart, ThumbPart, ForwardTrackPart, ForwardButtonPart }; - -class PlatformScrollbar : public Widget, public Scrollbar { +class PlatformScrollbar : public Scrollbar { public: - PlatformScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize); - - virtual ~PlatformScrollbar(); - - virtual bool isWidget() const { return true; } - - virtual void setParent(ScrollView*); - - virtual int width() const; - virtual int height() const; - virtual void setRect(const IntRect&); - virtual void setEnabled(bool); - virtual void paint(GraphicsContext*, const IntRect& damageRect); - - virtual bool handleMouseMoveEvent(const PlatformMouseEvent&); - virtual bool handleMouseOutEvent(const PlatformMouseEvent&); - virtual bool handleMousePressEvent(const PlatformMouseEvent&); - virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&); - - virtual IntRect windowClipRect() const; - - static void themeChanged(); - static int horizontalScrollbarHeight(ScrollbarControlSize size = RegularScrollbar); - static int verticalScrollbarWidth(ScrollbarControlSize size = RegularScrollbar); - - void autoscrollTimerFired(Timer<PlatformScrollbar>*); - -protected: - virtual void updateThumbPosition(); - virtual void updateThumbProportion(); - -private: - bool hasButtons() const; - bool hasThumb() const; - IntRect backButtonRect() const; - IntRect forwardButtonRect() const; - IntRect trackRect() const; - IntRect thumbRect() const; - IntRect gripperRect(const IntRect& thumbRect) const; - void splitTrack(const IntRect& trackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect) const; - - int thumbPosition() const; - int thumbLength() const; - int trackLength() const; - - void paintButton(GraphicsContext*, const IntRect& buttonRect, bool start, const IntRect& damageRect) const; - void paintTrack(GraphicsContext*, const IntRect& trackRect, bool start, const IntRect& damageRect) const; - void paintThumb(GraphicsContext*, const IntRect& thumbRect, const IntRect& damageRect) const; - void paintGripper(HDC, const IntRect& gripperRect) const; + static PassRefPtr<PlatformScrollbar> create(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size) + { + return adoptRef(new PlatformScrollbar(client, orientation, size)); + } - ScrollbarPart hitTest(const PlatformMouseEvent&); - - void startTimerIfNeeded(double delay); - void stopTimerIfNeeded(); - void autoscrollPressedPart(double delay); - ScrollDirection pressedPartScrollDirection(); - ScrollGranularity pressedPartScrollGranularity(); - - bool thumbUnderMouse(); - - void invalidatePart(ScrollbarPart); - void invalidateTrack(); - - ScrollbarPart m_hoveredPart; - ScrollbarPart m_pressedPart; - int m_pressedPos; - Timer<PlatformScrollbar> m_scrollTimer; - bool m_overlapsResizer; + PlatformScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize, ScrollbarTheme* = 0); }; } diff --git a/WebCore/platform/win/PlatformScrollBarSafari.cpp b/WebCore/platform/win/PlatformScrollBarSafari.cpp deleted file mode 100644 index 6485914..0000000 --- a/WebCore/platform/win/PlatformScrollBarSafari.cpp +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#ifdef USE_SAFARI_THEME - -#include "PlatformScrollBar.h" - -#include "EventHandler.h" -#include "FrameView.h" -#include "Frame.h" -#include "GraphicsContext.h" -#include "IntRect.h" -#include "PlatformMouseEvent.h" -#include "SoftLinking.h" - -#include <CoreGraphics/CoreGraphics.h> -#include <SafariTheme/SafariTheme.h> - -// FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow. - -using namespace std; - -namespace WebCore { - -using namespace SafariTheme; - -// FIXME: We should get these numbers from SafariTheme -static int cHorizontalWidth[] = { 15, 11 }; -static int cHorizontalHeight[] = { 15, 11 }; -static int cVerticalWidth[] = { 15, 11 }; -static int cVerticalHeight[] = { 15, 11 }; -static int cRealButtonLength[] = { 28, 21 }; -static int cButtonInset[] = { 14, 11 }; -static int cButtonHitInset[] = { 3, 2 }; -// cRealButtonLength - cButtonInset -static int cButtonLength[] = { 14, 10 }; -static int cThumbWidth[] = { 15, 11 }; -static int cThumbHeight[] = { 15, 11 }; -static int cThumbMinLength[] = { 26, 20 }; - -#if !defined(NDEBUG) && defined(USE_DEBUG_SAFARI_THEME) -SOFT_LINK_DEBUG_LIBRARY(SafariTheme) -#else -SOFT_LINK_LIBRARY(SafariTheme) -#endif - -SOFT_LINK(SafariTheme, paintThemePart, void, __stdcall, (ThemePart part, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state), (part, context, rect, size, state)) - -const double cInitialTimerDelay = 0.25; -const double cNormalTimerDelay = 0.05; - -PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size) - : Scrollbar(client, orientation, size), m_hoveredPart(NoPart), m_pressedPart(NoPart), m_pressedPos(0), - m_scrollTimer(this, &PlatformScrollbar::autoscrollTimerFired), - m_overlapsResizer(false) -{ - // Obtain the correct scrollbar sizes from the system. - if (!cHorizontalWidth) { - // FIXME: Get metics from SafariTheme - } - - if (orientation == VerticalScrollbar) - setFrameGeometry(IntRect(0, 0, cVerticalWidth[controlSize()], cVerticalHeight[controlSize()])); - else - setFrameGeometry(IntRect(0, 0, cHorizontalWidth[controlSize()], cHorizontalHeight[controlSize()])); -} - -PlatformScrollbar::~PlatformScrollbar() -{ - stopTimerIfNeeded(); -} - -void PlatformScrollbar::updateThumbPosition() -{ - invalidateTrack(); -} - -void PlatformScrollbar::updateThumbProportion() -{ - invalidateTrack(); -} - -static IntRect trackRepaintRect(const IntRect& trackRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize) -{ - IntRect paintRect(trackRect); - if (orientation == HorizontalScrollbar) - paintRect.inflateX(cButtonLength[controlSize]); - else - paintRect.inflateY(cButtonLength[controlSize]); - - return paintRect; -} - -static IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start) -{ - IntRect paintRect(buttonRect); - if (orientation == HorizontalScrollbar) { - paintRect.setWidth(cRealButtonLength[controlSize]); - if (!start) - paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - buttonRect.width())); - } else { - paintRect.setHeight(cRealButtonLength[controlSize]); - if (!start) - paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - buttonRect.height())); - } - - return paintRect; -} - -void PlatformScrollbar::invalidateTrack() -{ - IntRect rect = trackRepaintRect(trackRect(), m_orientation, controlSize()); - rect.move(-x(), -y()); - invalidateRect(rect); -} - -void PlatformScrollbar::invalidatePart(ScrollbarPart part) -{ - if (part == NoPart) - return; - - IntRect result; - switch (part) { - case BackButtonPart: - result = buttonRepaintRect(backButtonRect(), m_orientation, controlSize(), true); - break; - case ForwardButtonPart: - result = buttonRepaintRect(forwardButtonRect(), m_orientation, controlSize(), false); - break; - default: { - IntRect beforeThumbRect, thumbRect, afterThumbRect; - splitTrack(trackRect(), beforeThumbRect, thumbRect, afterThumbRect); - if (part == BackTrackPart) - result = beforeThumbRect; - else if (part == ForwardTrackPart) - result = afterThumbRect; - else - result = thumbRect; - } - } - result.move(-x(), -y()); - invalidateRect(result); -} - -int PlatformScrollbar::width() const -{ - return Widget::width(); -} - -int PlatformScrollbar::height() const -{ - return Widget::height(); -} - -void PlatformScrollbar::setRect(const IntRect& rect) -{ - // Get our window resizer rect and see if we overlap. Adjust to avoid the overlap - // if necessary. - IntRect adjustedRect(rect); - if (parent() && parent()->isFrameView()) { - bool overlapsResizer = false; - FrameView* view = static_cast<FrameView*>(parent()); - IntRect resizerRect = view->windowResizerRect(); - resizerRect.setLocation(view->convertFromContainingWindow(resizerRect.location())); - if (rect.intersects(resizerRect)) { - if (orientation() == HorizontalScrollbar) { - int overlap = rect.right() - resizerRect.x(); - if (overlap > 0 && resizerRect.right() >= rect.right()) { - adjustedRect.setWidth(rect.width() - overlap); - overlapsResizer = true; - } - } else { - int overlap = rect.bottom() - resizerRect.y(); - if (overlap > 0 && resizerRect.bottom() >= rect.bottom()) { - adjustedRect.setHeight(rect.height() - overlap); - overlapsResizer = true; - } - } - } - - if (overlapsResizer != m_overlapsResizer) { - m_overlapsResizer = overlapsResizer; - view->adjustOverlappingScrollbarCount(m_overlapsResizer ? 1 : -1); - } - } - - setFrameGeometry(adjustedRect); -} - -void PlatformScrollbar::setParent(ScrollView* parentView) -{ - if (!parentView && m_overlapsResizer && parent() && parent()->isFrameView()) - static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(-1); - Widget::setParent(parentView); -} - -void PlatformScrollbar::setEnabled(bool enabled) -{ - if (enabled != isEnabled()) { - Widget::setEnabled(enabled); - invalidate(); - } -} - -void PlatformScrollbar::paint(GraphicsContext* graphicsContext, const IntRect& damageRect) -{ - if (graphicsContext->updatingControlTints()) { - invalidate(); - return; - } - - if (graphicsContext->paintingDisabled()) - return; - - // Don't paint anything if the scrollbar doesn't intersect the damage rect. - if (!frameGeometry().intersects(damageRect)) - return; - - IntRect track = trackRect(); - paintTrack(graphicsContext, track, true, damageRect); - - if (hasButtons()) { - paintButton(graphicsContext, backButtonRect(), true, damageRect); - paintButton(graphicsContext, forwardButtonRect(), false, damageRect); - } - - if (hasThumb() && damageRect.intersects(track)) { - IntRect startTrackRect, thumbRect, endTrackRect; - splitTrack(track, startTrackRect, thumbRect, endTrackRect); - paintThumb(graphicsContext, thumbRect, damageRect); - } -} - -bool PlatformScrollbar::hasButtons() const -{ - return isEnabled() && (m_orientation == HorizontalScrollbar ? width() : height()) >= 2 * (cRealButtonLength[controlSize()] - cButtonHitInset[controlSize()]); -} - -bool PlatformScrollbar::hasThumb() const -{ - return isEnabled() && (m_orientation == HorizontalScrollbar ? width() : height()) >= 2 * cButtonInset[controlSize()] + cThumbMinLength[controlSize()] + 1; -} - -IntRect PlatformScrollbar::backButtonRect() const -{ - // Our desired rect is essentially 17x17. - - // Our actual rect will shrink to half the available space when - // we have < 34 pixels left. This allows the scrollbar - // to scale down and function even at tiny sizes. - if (m_orientation == HorizontalScrollbar) - return IntRect(x(), y(), cButtonLength[controlSize()], cHorizontalHeight[controlSize()]); - return IntRect(x(), y(), cVerticalWidth[controlSize()], cButtonLength[controlSize()]); -} - -IntRect PlatformScrollbar::forwardButtonRect() const -{ - // Our desired rect is essentially 17x17. - - // Our actual rect will shrink to half the available space when - // we have < 34 pixels left. This allows the scrollbar - // to scale down and function even at tiny sizes. - - if (m_orientation == HorizontalScrollbar) - return IntRect(x() + width() - cButtonLength[controlSize()], y(), cButtonLength[controlSize()], cHorizontalHeight[controlSize()]); - return IntRect(x(), y() + height() - cButtonLength[controlSize()], cVerticalWidth[controlSize()], cButtonLength[controlSize()]); -} - -IntRect PlatformScrollbar::trackRect() const -{ - if (m_orientation == HorizontalScrollbar) { - if (!hasButtons()) - return IntRect(x(), y(), width(), cHorizontalHeight[controlSize()]); - return IntRect(x() + cButtonLength[controlSize()], y(), width() - 2 * cButtonLength[controlSize()], cHorizontalHeight[controlSize()]); - } - - if (!hasButtons()) - return IntRect(x(), y(), cVerticalWidth[controlSize()], height()); - return IntRect(x(), y() + cButtonLength[controlSize()], cVerticalWidth[controlSize()], height() - 2 * cButtonLength[controlSize()]); -} - -IntRect PlatformScrollbar::thumbRect() const -{ - IntRect beforeThumbRect, thumbRect, afterThumbRect; - splitTrack(trackRect(), beforeThumbRect, thumbRect, afterThumbRect); - return thumbRect; -} - -void PlatformScrollbar::splitTrack(const IntRect& trackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect) const -{ - // This function won't even get called unless we're big enough to have some combination of these three rects where at least - // one of them is non-empty. - int thumbPos = thumbPosition(); - if (m_orientation == HorizontalScrollbar) { - thumbRect = IntRect(trackRect.x() + thumbPos, trackRect.y() + (trackRect.height() - cThumbHeight[controlSize()]) / 2, thumbLength(), cThumbHeight[controlSize()]); - beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), thumbPos, trackRect.height()); - afterThumbRect = IntRect(thumbRect.x() + thumbRect.width(), trackRect.y(), trackRect.right() - thumbRect.right(), trackRect.height()); - } else { - thumbRect = IntRect(trackRect.x() + (trackRect.width() - cThumbWidth[controlSize()]) / 2, trackRect.y() + thumbPos, cThumbWidth[controlSize()], thumbLength()); - beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), trackRect.width(), thumbPos); - afterThumbRect = IntRect(trackRect.x(), thumbRect.y() + thumbRect.height(), trackRect.width(), trackRect.bottom() - thumbRect.bottom()); - } -} - -int PlatformScrollbar::thumbPosition() const -{ - if (isEnabled()) - return (float)m_currentPos * (trackLength() - thumbLength()) / (m_totalSize - m_visibleSize); - return 0; -} - -int PlatformScrollbar::thumbLength() const -{ - if (!isEnabled()) - return 0; - - float proportion = (float)(m_visibleSize) / m_totalSize; - int trackLen = trackLength(); - int length = proportion * trackLen; - int minLength = cThumbMinLength[controlSize()]; - length = max(length, minLength); - if (length > trackLen) - length = 0; // Once the thumb is below the track length, it just goes away (to make more room for the track). - return length; -} - -int PlatformScrollbar::trackLength() const -{ - return (m_orientation == HorizontalScrollbar) ? trackRect().width() : trackRect().height(); -} - -void PlatformScrollbar::paintButton(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const -{ - if (!SafariThemeLibrary()) - return; - - IntRect paintRect = buttonRepaintRect(rect, m_orientation, controlSize(), start); - - if (!damageRect.intersects(paintRect)) - return; - - ThemePart part; - ThemeControlState state = 0; - if (m_client->isActive()) - state |= ActiveState; - if (m_orientation == HorizontalScrollbar) - part = start ? ScrollLeftArrowPart : ScrollRightArrowPart; - else - part = start ? ScrollUpArrowPart : ScrollDownArrowPart; - - if (isEnabled()) - state |= EnabledState; - if ((m_pressedPart == BackButtonPart && start) - || (m_pressedPart == ForwardButtonPart && !start)) - state |= PressedState; - - paintThemePart(part, context->platformContext(), paintRect, controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize, state); -} - -void PlatformScrollbar::paintTrack(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const -{ - if (!SafariThemeLibrary()) - return; - - IntRect paintRect = hasButtons() ? trackRepaintRect(rect, m_orientation, controlSize()) : rect; - - if (!damageRect.intersects(paintRect)) - return; - - ThemePart part = m_orientation == HorizontalScrollbar ? HScrollTrackPart : VScrollTrackPart; - ThemeControlState state = 0; - if (m_client->isActive()) - state |= ActiveState; - if (hasButtons()) - state |= EnabledState; - - paintThemePart(part, context->platformContext(), paintRect, controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize, state); -} - -void PlatformScrollbar::paintThumb(GraphicsContext* context, const IntRect& rect, const IntRect& damageRect) const -{ - if (!SafariThemeLibrary()) - return; - - if (!damageRect.intersects(rect)) - return; - - ThemePart part = m_orientation == HorizontalScrollbar ? HScrollThumbPart : VScrollThumbPart; - ThemeControlState state = 0; - if (m_client->isActive()) - state |= ActiveState; - if (isEnabled()) - state |= EnabledState; - - paintThemePart(part, context->platformContext(), rect, controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize, state); -} - -ScrollbarPart PlatformScrollbar::hitTest(const PlatformMouseEvent& evt) -{ - if (!isEnabled()) - return NoPart; - - IntPoint mousePosition = convertFromContainingWindow(evt.pos()); - mousePosition.move(x(), y()); - - if (hasButtons()) { - if (backButtonRect().contains(mousePosition)) - return BackButtonPart; - - if (forwardButtonRect().contains(mousePosition)) - return ForwardButtonPart; - } - - if (!hasThumb()) - return NoPart; - - IntRect track = trackRect(); - if (track.contains(mousePosition)) { - IntRect beforeThumbRect, thumbRect, afterThumbRect; - splitTrack(track, beforeThumbRect, thumbRect, afterThumbRect); - if (beforeThumbRect.contains(mousePosition)) - return BackTrackPart; - if (thumbRect.contains(mousePosition)) - return ThumbPart; - return ForwardTrackPart; - } - return NoPart; -} - -bool PlatformScrollbar::handleMouseMoveEvent(const PlatformMouseEvent& evt) -{ - if (m_pressedPart == ThumbPart) { - // Drag the thumb. - int thumbPos = thumbPosition(); - int thumbLen = thumbLength(); - int trackLen = trackLength(); - int maxPos = trackLen - thumbLen; - int delta = 0; - if (m_orientation == HorizontalScrollbar) - delta = convertFromContainingWindow(evt.pos()).x() - m_pressedPos; - else - delta = convertFromContainingWindow(evt.pos()).y() - m_pressedPos; - - if (delta > 0) - // The mouse moved down/right. - delta = min(maxPos - thumbPos, delta); - else if (delta < 0) - // The mouse moved up/left. - delta = max(-thumbPos, delta); - - if (delta != 0) { - setValue((float)(thumbPos + delta) * (m_totalSize - m_visibleSize) / (trackLen - thumbLen)); - m_pressedPos += thumbPosition() - thumbPos; - } - - return true; - } - - if (m_pressedPart != NoPart) - m_pressedPos = (m_orientation == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y()); - - ScrollbarPart part = hitTest(evt); - if (part != m_hoveredPart) { - if (m_pressedPart != NoPart) { - if (part == m_pressedPart) { - // The mouse is moving back over the pressed part. We - // need to start up the timer action again. - startTimerIfNeeded(cNormalTimerDelay); - invalidatePart(m_pressedPart); - } else if (m_hoveredPart == m_pressedPart) { - // The mouse is leaving the pressed part. Kill our timer - // if needed. - stopTimerIfNeeded(); - invalidatePart(m_pressedPart); - } - } else { - invalidatePart(part); - invalidatePart(m_hoveredPart); - } - m_hoveredPart = part; - } - - return true; -} - -bool PlatformScrollbar::handleMouseOutEvent(const PlatformMouseEvent& evt) -{ - invalidatePart(m_hoveredPart); - m_hoveredPart = NoPart; - - return true; -} - -bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& evt) -{ - m_pressedPart = hitTest(evt); - m_pressedPos = (m_orientation == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y()); - invalidatePart(m_pressedPart); - autoscrollPressedPart(cInitialTimerDelay); - return true; -} - -bool PlatformScrollbar::handleMouseReleaseEvent(const PlatformMouseEvent& evt) -{ - invalidatePart(m_pressedPart); - m_pressedPart = NoPart; - m_pressedPos = 0; - stopTimerIfNeeded(); - - if (parent() && parent()->isFrameView()) - static_cast<FrameView*>(parent())->frame()->eventHandler()->setMousePressed(false); - - return true; -} - -void PlatformScrollbar::startTimerIfNeeded(double delay) -{ - // Don't do anything for the thumb. - if (m_pressedPart == ThumbPart) - return; - - // Handle the track. We halt track scrolling once the thumb is level - // with us. - if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse()) { - invalidatePart(m_pressedPart); - m_hoveredPart = ThumbPart; - return; - } - - // We can't scroll if we've hit the beginning or end. - ScrollDirection dir = pressedPartScrollDirection(); - if (dir == ScrollUp || dir == ScrollLeft) { - if (m_currentPos == 0) - return; - } else { - if (m_currentPos == m_totalSize - m_visibleSize) - return; - } - - m_scrollTimer.startOneShot(delay); -} - -void PlatformScrollbar::stopTimerIfNeeded() -{ - if (m_scrollTimer.isActive()) - m_scrollTimer.stop(); -} - -void PlatformScrollbar::autoscrollPressedPart(double delay) -{ - // Don't do anything for the thumb or if nothing was pressed. - if (m_pressedPart == ThumbPart || m_pressedPart == NoPart) - return; - - // Handle the track. - if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse()) { - invalidatePart(m_pressedPart); - m_hoveredPart = ThumbPart; - return; - } - - // Handle the arrows and track. - if (scroll(pressedPartScrollDirection(), pressedPartScrollGranularity())) - startTimerIfNeeded(delay); -} - -void PlatformScrollbar::autoscrollTimerFired(Timer<PlatformScrollbar>*) -{ - autoscrollPressedPart(cNormalTimerDelay); -} - -ScrollDirection PlatformScrollbar::pressedPartScrollDirection() -{ - if (m_orientation == HorizontalScrollbar) { - if (m_pressedPart == BackButtonPart || m_pressedPart == BackTrackPart) - return ScrollLeft; - return ScrollRight; - } else { - if (m_pressedPart == BackButtonPart || m_pressedPart == BackTrackPart) - return ScrollUp; - return ScrollDown; - } -} - -ScrollGranularity PlatformScrollbar::pressedPartScrollGranularity() -{ - if (m_pressedPart == BackButtonPart || m_pressedPart == ForwardButtonPart) - return ScrollByLine; - return ScrollByPage; -} - -bool PlatformScrollbar::thumbUnderMouse() -{ - // Construct a rect. - IntRect thumb = thumbRect(); - thumb.move(-x(), -y()); - int begin = (m_orientation == HorizontalScrollbar) ? thumb.x() : thumb.y(); - int end = (m_orientation == HorizontalScrollbar) ? thumb.right() : thumb.bottom(); - return (begin <= m_pressedPos && m_pressedPos < end); -} - -int PlatformScrollbar::horizontalScrollbarHeight(ScrollbarControlSize controlSize) -{ - return cHorizontalWidth[controlSize]; -} - -int PlatformScrollbar::verticalScrollbarWidth(ScrollbarControlSize controlSize) -{ - return cVerticalHeight[controlSize]; -} - -IntRect PlatformScrollbar::windowClipRect() const -{ - IntRect clipRect(0, 0, width(), height()); - clipRect = convertToContainingWindow(clipRect); - if (m_client) - clipRect.intersect(m_client->windowClipRect()); - return clipRect; -} - -void PlatformScrollbar::paintGripper(HDC hdc, const IntRect& rect) const -{ -} - -IntRect PlatformScrollbar::gripperRect(const IntRect& thumbRect) const -{ - return IntRect(); -} - -void PlatformScrollbar::themeChanged() -{ -} - -} - -#endif // defined(USE_SAFARI_THEME) diff --git a/WebCore/platform/win/WebCoreHistory.cpp b/WebCore/platform/win/PlatformScrollBarWin.cpp index 1d3fdf9..aa5333b 100644 --- a/WebCore/platform/win/WebCoreHistory.cpp +++ b/WebCore/platform/win/PlatformScrollBarWin.cpp @@ -1,5 +1,6 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Brent Fulgham * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -20,28 +21,23 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" -#include "WebCoreHistory.h" +#include "PlatformScrollBar.h" -namespace WebCore { +#include "FrameView.h" +#include "ScrollbarClient.h" +#include "ScrollbarTheme.h" -static WebCoreHistoryProvider* _historyProvider = 0; +namespace WebCore { -void WebCoreHistory::setHistoryProvider(WebCoreHistoryProvider* h) +PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size, + ScrollbarTheme* theme) + : Scrollbar(client, orientation, size, theme) { - if (_historyProvider == h) - return; - - delete _historyProvider; - _historyProvider = h; } -WebCoreHistoryProvider* WebCoreHistory::historyProvider() -{ - return _historyProvider; } -} diff --git a/WebCore/platform/win/PopupMenuWin.cpp b/WebCore/platform/win/PopupMenuWin.cpp index c44763d..64b8a59 100644 --- a/WebCore/platform/win/PopupMenuWin.cpp +++ b/WebCore/platform/win/PopupMenuWin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,9 +31,10 @@ #include "Page.h" #include "PlatformMouseEvent.h" #include "PlatformScreen.h" -#include "PlatformScrollBar.h" #include "RenderTheme.h" #include "RenderView.h" +#include "Scrollbar.h" +#include "ScrollbarTheme.h" #include "SimpleFontData.h" #include <tchar.h> #include <windows.h> @@ -66,7 +67,7 @@ static inline bool isASCIIPrintable(unsigned c) PopupMenu::PopupMenu(PopupMenuClient* client) : m_popupClient(client) - , m_scrollBar(0) + , m_scrollbar(0) , m_popup(0) , m_DC(0) , m_bmp(0) @@ -105,7 +106,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) m_popup = ::CreateWindowEx(exStyle, kPopupWindowClassName, _T("PopupMenu"), WS_POPUP | WS_BORDER, 0, 0, 0, 0, - v->containingWindow(), 0, 0, 0); + v->hostWindow()->platformWindow(), 0, 0, 0); if (!m_popup) return; @@ -114,11 +115,10 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) ::SetLayeredWindowAttributes(m_popup, 0, (255 * popupWindowAlphaPercent) / 100, LWA_ALPHA); } - if (!m_scrollBar) + if (!m_scrollbar) if (visibleItems() < client()->listSize()) { // We need a scroll bar - m_scrollBar = new PlatformScrollbar(this, VerticalScrollbar, SmallScrollbar); - m_scrollBar->setContainingWindow(m_popup); + m_scrollbar = client()->createScrollbar(this, VerticalScrollbar, SmallScrollbar); } ::SetWindowPos(m_popup, HWND_TOP, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), 0); @@ -132,7 +132,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) if (shouldAnimate) { RECT viewRect = {0}; - ::GetWindowRect(v->containingWindow(), &viewRect); + ::GetWindowRect(v->hostWindow()->platformWindow(), &viewRect); if (!::IsRectEmpty(&viewRect)) { // Popups should slide into view away from the <select> box @@ -167,14 +167,14 @@ void PopupMenu::calculatePositionAndSize(const IntRect& r, FrameView* v) // Then, translate to screen coordinates POINT location(rScreenCoords.location()); - if (!::ClientToScreen(v->containingWindow(), &location)) + if (!::ClientToScreen(v->hostWindow()->platformWindow(), &location)) return; rScreenCoords.setLocation(location); // First, determine the popup's height int itemCount = client()->listSize(); - m_itemHeight = client()->clientStyle()->font().height() + optionSpacingMiddle; + m_itemHeight = client()->menuStyle().font().height() + optionSpacingMiddle; int naturalHeight = m_itemHeight * itemCount; int popupHeight = min(maxPopupHeight, naturalHeight); // The popup should show an integral number of items (i.e. no partial items should be visible) @@ -187,12 +187,20 @@ void PopupMenu::calculatePositionAndSize(const IntRect& r, FrameView* v) if (text.isEmpty()) continue; - popupWidth = max(popupWidth, client()->clientStyle()->font().width(TextRun(text.characters(), text.length()))); + Font itemFont = client()->menuStyle().font(); + if (client()->itemIsLabel(i)) { + FontDescription d = itemFont.fontDescription(); + d.setWeight(d.bolderWeight()); + itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing()); + itemFont.update(m_popupClient->fontSelector()); + } + + popupWidth = max(popupWidth, itemFont.width(TextRun(text.characters(), text.length()))); } if (naturalHeight > maxPopupHeight) // We need room for a scrollbar - popupWidth += PlatformScrollbar::verticalScrollbarWidth(SmallScrollbar); + popupWidth += ScrollbarTheme::nativeTheme()->scrollbarThickness(SmallScrollbar); // Add padding to align the popup text with the <select> text // Note: We can't add paddingRight() because that value includes the width @@ -353,8 +361,8 @@ void PopupMenu::invalidateItem(int index) IntRect damageRect(clientRect()); damageRect.setY(m_itemHeight * (index - m_scrollOffset)); damageRect.setHeight(m_itemHeight); - if (m_scrollBar) - damageRect.setWidth(damageRect.width() - m_scrollBar->frameGeometry().width()); + if (m_scrollbar) + damageRect.setWidth(damageRect.width() - m_scrollbar->frameRect().width()); RECT r = damageRect; ::InvalidateRect(m_popup, &r, TRUE); @@ -388,18 +396,18 @@ void PopupMenu::reduceWheelDelta(int delta) bool PopupMenu::scrollToRevealSelection() { - if (!m_scrollBar) + if (!m_scrollbar) return false; int index = focusedIndex(); if (index < m_scrollOffset) { - m_scrollBar->setValue(index); + m_scrollbar->setValue(index); return true; } if (index >= m_scrollOffset + visibleItems()) { - m_scrollBar->setValue(index - visibleItems() + 1); + m_scrollbar->setValue(index - visibleItems() + 1); return true; } @@ -477,26 +485,24 @@ void PopupMenu::paint(const IntRect& damageRect, HDC hdc) IntRect listRect = damageRect; listRect.move(IntSize(0, m_scrollOffset * m_itemHeight)); - RenderStyle* clientStyle = client()->clientStyle(); - for (int y = listRect.y(); y < listRect.bottom(); y += m_itemHeight) { int index = y / m_itemHeight; Color optionBackgroundColor, optionTextColor; - RenderStyle* itemStyle = client()->itemStyle(index); + PopupMenuStyle itemStyle = client()->itemStyle(index); if (index == focusedIndex()) { optionBackgroundColor = theme()->activeListBoxSelectionBackgroundColor(); optionTextColor = theme()->activeListBoxSelectionForegroundColor(); } else { - optionBackgroundColor = client()->itemBackgroundColor(index); - optionTextColor = itemStyle->color(); + optionBackgroundColor = itemStyle.backgroundColor(); + optionTextColor = itemStyle.foregroundColor(); } // itemRect is in client coordinates IntRect itemRect(0, (index - m_scrollOffset) * m_itemHeight, damageRect.width(), m_itemHeight); // Draw the background for this menu item - if (itemStyle->visibility() != HIDDEN) + if (itemStyle.isVisible()) context.fillRect(itemRect, optionBackgroundColor); if (client()->itemIsSeparator(index)) { @@ -513,25 +519,25 @@ void PopupMenu::paint(const IntRect& damageRect, HDC hdc) context.setFillColor(optionTextColor); - Font itemFont = client()->clientStyle()->font(); + Font itemFont = client()->menuStyle().font(); if (client()->itemIsLabel(index)) { FontDescription d = itemFont.fontDescription(); - d.setBold(true); + d.setWeight(d.bolderWeight()); itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing()); itemFont.update(m_popupClient->fontSelector()); } context.setFont(itemFont); // Draw the item text - if (itemStyle->visibility() != HIDDEN) { + if (itemStyle.isVisible()) { int textX = max(0, client()->clientPaddingLeft() - client()->clientInsetLeft()); int textY = itemRect.y() + itemFont.ascent() + (itemRect.height() - itemFont.height()) / 2; context.drawBidiText(textRun, IntPoint(textX, textY)); } } - if (m_scrollBar) - m_scrollBar->paint(&context, damageRect); + if (m_scrollbar) + m_scrollbar->paint(&context, damageRect); if (!hdc) hdc = ::GetDC(m_popup); @@ -541,7 +547,7 @@ void PopupMenu::paint(const IntRect& damageRect, HDC hdc) void PopupMenu::valueChanged(Scrollbar* scrollBar) { - ASSERT(m_scrollBar); + ASSERT(m_scrollbar); if (!m_popup) return; @@ -564,20 +570,23 @@ void PopupMenu::valueChanged(Scrollbar* scrollBar) #endif IntRect listRect = clientRect(); - if (m_scrollBar) - listRect.setWidth(listRect.width() - m_scrollBar->frameGeometry().width()); + if (m_scrollbar) + listRect.setWidth(listRect.width() - m_scrollbar->frameRect().width()); RECT r = listRect; ::ScrollWindowEx(m_popup, 0, scrolledLines * m_itemHeight, &r, 0, 0, 0, flags); - if (m_scrollBar) { - r = m_scrollBar->frameGeometry(); + if (m_scrollbar) { + r = m_scrollbar->frameRect(); ::InvalidateRect(m_popup, &r, TRUE); } ::UpdateWindow(m_popup); } -IntRect PopupMenu::windowClipRect() const +void PopupMenu::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect) { - return m_windowRect; + IntRect scrollRect = rect; + scrollRect.move(scrollbar->x(), scrollbar->y()); + RECT r = scrollRect; + ::InvalidateRect(m_popup, &r, false); } static ATOM registerPopup() @@ -617,14 +626,14 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA switch (message) { case WM_SIZE: - if (popup && popup->scrollBar()) { + if (popup && popup->scrollbar()) { IntSize size(LOWORD(lParam), HIWORD(lParam)); - popup->scrollBar()->setRect(IntRect(size.width() - popup->scrollBar()->width(), 0, popup->scrollBar()->width(), size.height())); + popup->scrollbar()->setFrameRect(IntRect(size.width() - popup->scrollbar()->width(), 0, popup->scrollbar()->width(), size.height())); int visibleItems = popup->visibleItems(); - popup->scrollBar()->setEnabled(visibleItems < popup->client()->listSize()); - popup->scrollBar()->setSteps(1, max(1, visibleItems - 1)); - popup->scrollBar()->setProportion(visibleItems, popup->client()->listSize()); + popup->scrollbar()->setEnabled(visibleItems < popup->client()->listSize()); + popup->scrollbar()->setSteps(1, max(1, visibleItems - 1)); + popup->scrollbar()->setProportion(visibleItems, popup->client()->listSize()); } break; case WM_ACTIVATE: @@ -675,13 +684,13 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA } break; case VK_TAB: - ::SendMessage(popup->client()->clientDocument()->view()->containingWindow(), message, wParam, lParam); + ::SendMessage(popup->client()->hostWindow()->platformWindow(), message, wParam, lParam); popup->client()->hidePopup(); break; default: if (isASCIIPrintable(wParam)) // Send the keydown to the WebView so it can be used for type-to-select. - ::PostMessage(popup->client()->clientDocument()->view()->containingWindow(), message, wParam, lParam); + ::PostMessage(popup->client()->hostWindow()->platformWindow(), message, wParam, lParam); else lResult = 1; break; @@ -714,13 +723,13 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA case WM_MOUSEMOVE: if (popup) { IntPoint mousePoint(MAKEPOINTS(lParam)); - if (popup->scrollBar()) { - IntRect scrollBarRect = popup->scrollBar()->frameGeometry(); + if (popup->scrollbar()) { + IntRect scrollBarRect = popup->scrollbar()->frameRect(); if (popup->scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) { // Put the point into coordinates relative to the scroll bar mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y()); PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y())); - popup->scrollBar()->handleMouseMoveEvent(event); + popup->scrollbar()->mouseMoved(event); break; } } @@ -745,13 +754,13 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA if (popup) { ::SetCapture(popup->popupHandle()); IntPoint mousePoint(MAKEPOINTS(lParam)); - if (popup->scrollBar()) { - IntRect scrollBarRect = popup->scrollBar()->frameGeometry(); + if (popup->scrollbar()) { + IntRect scrollBarRect = popup->scrollbar()->frameRect(); if (scrollBarRect.contains(mousePoint)) { // Put the point into coordinates relative to the scroll bar mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y()); PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y())); - popup->scrollBar()->handleMousePressEvent(event); + popup->scrollbar()->mouseDown(event); popup->setScrollbarCapturingMouse(true); break; } @@ -763,16 +772,16 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA case WM_LBUTTONUP: if (popup) { IntPoint mousePoint(MAKEPOINTS(lParam)); - if (popup->scrollBar()) { + if (popup->scrollbar()) { ::ReleaseCapture(); - IntRect scrollBarRect = popup->scrollBar()->frameGeometry(); + IntRect scrollBarRect = popup->scrollbar()->frameRect(); if (popup->scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) { popup->setScrollbarCapturingMouse(false); // Put the point into coordinates relative to the scroll bar mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y()); PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y())); - popup->scrollBar()->handleMouseReleaseEvent(event); - // FIXME: This is a hack to work around PlatformScrollbar not invalidating correctly when it doesn't have a parent widget + popup->scrollbar()->mouseUp(); + // FIXME: This is a hack to work around Scrollbar not invalidating correctly when it doesn't have a parent widget RECT r = scrollBarRect; ::InvalidateRect(popup->popupHandle(), &r, TRUE); break; @@ -791,7 +800,7 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA } break; case WM_MOUSEWHEEL: - if (popup && popup->scrollBar()) { + if (popup && popup->scrollbar()) { int i = 0; for (popup->incrementWheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)); abs(popup->wheelDelta()) >= WHEEL_DELTA; popup->reduceWheelDelta(WHEEL_DELTA)) if (popup->wheelDelta() > 0) @@ -799,7 +808,7 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA else --i; - popup->scrollBar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i)); + popup->scrollbar()->scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i)); } break; case WM_PAINT: diff --git a/WebCore/platform/win/ScrollViewWin.cpp b/WebCore/platform/win/ScrollViewWin.cpp deleted file mode 100644 index 705898a..0000000 --- a/WebCore/platform/win/ScrollViewWin.cpp +++ /dev/null @@ -1,858 +0,0 @@ -/* - * 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 COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ScrollView.h" - -#include "Chrome.h" -#include "ChromeClient.h" -#include "FloatRect.h" -#include "FocusController.h" -#include "Frame.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "IntRect.h" -#include "NotImplemented.h" -#include "Page.h" -#include "PlatformScrollBar.h" -#include "PlatformMouseEvent.h" -#include "PlatformWheelEvent.h" -#include "RenderTheme.h" -#include "ScrollBar.h" -#include <algorithm> -#include <winsock2.h> -#include <windows.h> -#include <wtf/Assertions.h> -#include <wtf/HashSet.h> - -using namespace std; - -namespace WebCore { - -class ScrollView::ScrollViewPrivate : public ScrollbarClient { -public: - ScrollViewPrivate(ScrollView* view) - : m_view(view) - , m_hasStaticBackground(false) - , m_scrollbarsSuppressed(false) - , m_inUpdateScrollbars(false) - , m_scrollbarsAvoidingResizer(0) - , m_vScrollbarMode(ScrollbarAuto) - , m_hScrollbarMode(ScrollbarAuto) - , m_visible(false) - , m_attachedToWindow(false) - { - } - - ~ScrollViewPrivate() - { - setHasHorizontalScrollbar(false); - setHasVerticalScrollbar(false); - } - - void setHasHorizontalScrollbar(bool hasBar); - void setHasVerticalScrollbar(bool hasBar); - - virtual void valueChanged(Scrollbar*); - virtual IntRect windowClipRect() const; - virtual bool isActive() const; - - void scrollBackingStore(const IntSize& scrollDelta); - - void setAllowsScrolling(bool); - bool allowsScrolling() const; - - ScrollView* m_view; - IntSize m_scrollOffset; - IntSize m_contentsSize; - bool m_hasStaticBackground; - bool m_scrollbarsSuppressed; - bool m_inUpdateScrollbars; - int m_scrollbarsAvoidingResizer; - ScrollbarMode m_vScrollbarMode; - ScrollbarMode m_hScrollbarMode; - RefPtr<PlatformScrollbar> m_vBar; - RefPtr<PlatformScrollbar> m_hBar; - HRGN m_dirtyRegion; - HashSet<Widget*> m_children; - bool m_visible; - bool m_attachedToWindow; -}; - -void ScrollView::ScrollViewPrivate::setHasHorizontalScrollbar(bool hasBar) -{ - if (Scrollbar::hasPlatformScrollbars()) { - if (hasBar && !m_hBar) { - m_hBar = new PlatformScrollbar(this, HorizontalScrollbar, RegularScrollbar); - m_view->addChild(m_hBar.get()); - } else if (!hasBar && m_hBar) { - m_view->removeChild(m_hBar.get()); - m_hBar = 0; - } - } -} - -void ScrollView::ScrollViewPrivate::setHasVerticalScrollbar(bool hasBar) -{ - if (Scrollbar::hasPlatformScrollbars()) { - if (hasBar && !m_vBar) { - m_vBar = new PlatformScrollbar(this, VerticalScrollbar, RegularScrollbar); - m_view->addChild(m_vBar.get()); - } else if (!hasBar && m_vBar) { - m_view->removeChild(m_vBar.get()); - m_vBar = 0; - } - } -} - -void ScrollView::ScrollViewPrivate::valueChanged(Scrollbar* bar) -{ - // Figure out if we really moved. - IntSize newOffset = m_scrollOffset; - if (bar) { - if (bar == m_hBar) - newOffset.setWidth(bar->value()); - else if (bar == m_vBar) - newOffset.setHeight(bar->value()); - } - IntSize scrollDelta = newOffset - m_scrollOffset; - if (scrollDelta == IntSize()) - return; - m_scrollOffset = newOffset; - - if (m_scrollbarsSuppressed) - return; - - static_cast<FrameView*>(m_view)->frame()->sendScrollEvent(); - scrollBackingStore(scrollDelta); -} - -void ScrollView::ScrollViewPrivate::scrollBackingStore(const IntSize& scrollDelta) -{ - // Since scrolling is double buffered, we will be blitting the scroll view's intersection - // with the clip rect every time to keep it smooth. - HWND containingWindowHandle = m_view->containingWindow(); - IntRect clipRect = m_view->windowClipRect(); - IntRect scrollViewRect = m_view->convertToContainingWindow(IntRect(0, 0, m_view->visibleWidth(), m_view->visibleHeight())); - IntRect updateRect = clipRect; - updateRect.intersect(scrollViewRect); - RECT r = updateRect; - ::InvalidateRect(containingWindowHandle, &r, false); - - if (!m_hasStaticBackground) // The main frame can just blit the WebView window - // FIXME: Find a way to blit subframes without blitting overlapping content - m_view->scrollBackingStore(-scrollDelta.width(), -scrollDelta.height(), scrollViewRect, clipRect); - else { - // We need to go ahead and repaint the entire backing store. Do it now before moving the - // plugins. - m_view->addToDirtyRegion(updateRect); - m_view->updateBackingStore(); - } - - // This call will move child HWNDs (plugins) and invalidate them as well. - m_view->geometryChanged(); - - // Now update the window (which should do nothing but a blit of the backing store's updateRect and so should - // be very fast). - ::UpdateWindow(containingWindowHandle); -} - -void ScrollView::ScrollViewPrivate::setAllowsScrolling(bool flag) -{ - if (flag && m_vScrollbarMode == ScrollbarAlwaysOff) - m_vScrollbarMode = ScrollbarAuto; - else if (!flag) - m_vScrollbarMode = ScrollbarAlwaysOff; - - if (flag && m_hScrollbarMode == ScrollbarAlwaysOff) - m_hScrollbarMode = ScrollbarAuto; - else if (!flag) - m_hScrollbarMode = ScrollbarAlwaysOff; - - m_view->updateScrollbars(m_scrollOffset); -} - -bool ScrollView::ScrollViewPrivate::allowsScrolling() const -{ - // Return YES if either horizontal or vertical scrolling is allowed. - return m_hScrollbarMode != ScrollbarAlwaysOff || m_vScrollbarMode != ScrollbarAlwaysOff; -} - -IntRect ScrollView::ScrollViewPrivate::windowClipRect() const -{ - return static_cast<const FrameView*>(m_view)->windowClipRect(false); -} - -bool ScrollView::ScrollViewPrivate::isActive() const -{ - Page* page = static_cast<const FrameView*>(m_view)->frame()->page(); - return page && page->focusController()->isActive(); -} - -ScrollView::ScrollView() - : m_data(new ScrollViewPrivate(this)) -{ -} - -ScrollView::~ScrollView() -{ - delete m_data; -} - -void ScrollView::updateContents(const IntRect& rect, bool now) -{ - if (rect.isEmpty()) - return; - - IntPoint windowPoint = contentsToWindow(rect.location()); - IntRect containingWindowRect = rect; - containingWindowRect.setLocation(windowPoint); - - RECT containingWindowRectWin = containingWindowRect; - HWND containingWindowHandle = containingWindow(); - - ::InvalidateRect(containingWindowHandle, &containingWindowRectWin, false); - - // Cache the dirty spot. - addToDirtyRegion(containingWindowRect); - - if (now) - ::UpdateWindow(containingWindowHandle); -} - -void ScrollView::update() -{ - ::UpdateWindow(containingWindow()); -} - -int ScrollView::visibleWidth() const -{ - return max(0, width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0)); -} - -int ScrollView::visibleHeight() const -{ - return max(0, height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0)); -} - -FloatRect ScrollView::visibleContentRect() const -{ - return FloatRect(contentsX(), contentsY(), visibleWidth(), visibleHeight()); -} - -FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const -{ - // external scrollers not supported for now - return visibleContentRect(); -} - -void ScrollView::setContentsPos(int newX, int newY) -{ - int dx = newX - contentsX(); - int dy = newY - contentsY(); - scrollBy(dx, dy); -} - -void ScrollView::resizeContents(int w, int h) -{ - IntSize newContentsSize(w, h); - if (m_data->m_contentsSize != newContentsSize) { - m_data->m_contentsSize = newContentsSize; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setFrameGeometry(const IntRect& newGeometry) -{ - IntRect oldGeometry = frameGeometry(); - Widget::setFrameGeometry(newGeometry); - - if (newGeometry == oldGeometry) - return; - - if (newGeometry.width() != oldGeometry.width() || newGeometry.height() != oldGeometry.height()) { - updateScrollbars(m_data->m_scrollOffset); - static_cast<FrameView*>(this)->setNeedsLayout(); - } - - geometryChanged(); -} - -int ScrollView::contentsX() const -{ - return scrollOffset().width(); -} - -int ScrollView::contentsY() const -{ - return scrollOffset().height(); -} - -int ScrollView::contentsWidth() const -{ - return m_data->m_contentsSize.width(); -} - -int ScrollView::contentsHeight() const -{ - return m_data->m_contentsSize.height(); -} - -IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const -{ - IntPoint viewPoint = convertFromContainingWindow(windowPoint); - return viewPoint + scrollOffset(); -} - -IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const -{ - IntPoint viewPoint = contentsPoint - scrollOffset(); - return convertToContainingWindow(viewPoint); -} - -IntPoint ScrollView::convertChildToSelf(const Widget* child, const IntPoint& point) const -{ - IntPoint newPoint = point; - if (child != m_data->m_hBar && child != m_data->m_vBar) - newPoint = point - scrollOffset(); - return Widget::convertChildToSelf(child, newPoint); -} - -IntPoint ScrollView::convertSelfToChild(const Widget* child, const IntPoint& point) const -{ - IntPoint newPoint = point; - if (child != m_data->m_hBar && child != m_data->m_vBar) - newPoint = point + scrollOffset(); - return Widget::convertSelfToChild(child, newPoint); -} - -IntSize ScrollView::scrollOffset() const -{ - return m_data->m_scrollOffset; -} - -IntSize ScrollView::maximumScroll() const -{ - IntSize delta = (m_data->m_contentsSize - IntSize(visibleWidth(), visibleHeight())) - scrollOffset(); - delta.clampNegativeToZero(); - return delta; -} - -void ScrollView::scrollBy(int dx, int dy) -{ - IntSize scrollOffset = m_data->m_scrollOffset; - IntSize newScrollOffset = scrollOffset + IntSize(dx, dy).shrunkTo(maximumScroll()); - newScrollOffset.clampNegativeToZero(); - - if (newScrollOffset == scrollOffset) - return; - - updateScrollbars(newScrollOffset); -} - -void ScrollView::scrollRectIntoViewRecursively(const IntRect& r) -{ - IntPoint p(max(0, r.x()), max(0, r.y())); - ScrollView* view = this; - while (view) { - view->setContentsPos(p.x(), p.y()); - p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height()); - view = static_cast<ScrollView*>(view->parent()); - } -} - -WebCore::ScrollbarMode ScrollView::hScrollbarMode() const -{ - return m_data->m_hScrollbarMode; -} - -WebCore::ScrollbarMode ScrollView::vScrollbarMode() const -{ - return m_data->m_vScrollbarMode; -} - -void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnSuppress) -{ - m_data->m_scrollbarsSuppressed = suppressed; - if (repaintOnSuppress && !suppressed) { - if (m_data->m_hBar) - m_data->m_hBar->invalidate(); - if (m_data->m_vBar) - m_data->m_vBar->invalidate(); - - // Invalidate the scroll corner too on unsuppress. - IntRect hCorner; - if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) { - hCorner = IntRect(m_data->m_hBar->width(), - height() - m_data->m_hBar->height(), - width() - m_data->m_hBar->width(), - m_data->m_hBar->height()); - invalidateRect(hCorner); - } - - if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) { - IntRect vCorner(width() - m_data->m_vBar->width(), - m_data->m_vBar->height(), - m_data->m_vBar->width(), - height() - m_data->m_vBar->height()); - if (vCorner != hCorner) - invalidateRect(vCorner); - } - } -} - -void ScrollView::setHScrollbarMode(ScrollbarMode newMode) -{ - if (m_data->m_hScrollbarMode != newMode) { - m_data->m_hScrollbarMode = newMode; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setVScrollbarMode(ScrollbarMode newMode) -{ - if (m_data->m_vScrollbarMode != newMode) { - m_data->m_vScrollbarMode = newMode; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setScrollbarsMode(ScrollbarMode newMode) -{ - if (m_data->m_hScrollbarMode != newMode || - m_data->m_vScrollbarMode != newMode) { - m_data->m_hScrollbarMode = m_data->m_vScrollbarMode = newMode; - updateScrollbars(m_data->m_scrollOffset); - } -} - -void ScrollView::setStaticBackground(bool flag) -{ - m_data->m_hasStaticBackground = flag; -} - -void ScrollView::updateScrollbars(const IntSize& desiredOffset) -{ - // Don't allow re-entrancy into this function. - if (m_data->m_inUpdateScrollbars) - return; - - // FIXME: This code is here so we don't have to fork FrameView.h/.cpp. - // In the end, FrameView should just merge with ScrollView. - if (static_cast<const FrameView*>(this)->frame()->prohibitsScrolling()) - return; - - m_data->m_inUpdateScrollbars = true; - - bool hasVerticalScrollbar = m_data->m_vBar; - bool hasHorizontalScrollbar = m_data->m_hBar; - bool oldHasVertical = hasVerticalScrollbar; - bool oldHasHorizontal = hasHorizontalScrollbar; - ScrollbarMode hScroll = m_data->m_hScrollbarMode; - ScrollbarMode vScroll = m_data->m_vScrollbarMode; - - const int cVerticalWidth = PlatformScrollbar::verticalScrollbarWidth(); - const int cHorizontalHeight = PlatformScrollbar::horizontalScrollbarHeight(); - - for (int pass = 0; pass < 2; pass++) { - bool scrollsVertically; - bool scrollsHorizontally; - - if (!m_data->m_scrollbarsSuppressed && (hScroll == ScrollbarAuto || vScroll == ScrollbarAuto)) { - // Do a layout if pending before checking if scrollbars are needed. - if (hasVerticalScrollbar != oldHasVertical || hasHorizontalScrollbar != oldHasHorizontal) - static_cast<FrameView*>(this)->layout(); - - scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() > height()); - if (scrollsVertically) - scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() + cVerticalWidth > width()); - else { - scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() > width()); - if (scrollsHorizontally) - scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() + cHorizontalHeight > height()); - } - } - else { - scrollsHorizontally = (hScroll == ScrollbarAuto) ? hasHorizontalScrollbar : (hScroll == ScrollbarAlwaysOn); - scrollsVertically = (vScroll == ScrollbarAuto) ? hasVerticalScrollbar : (vScroll == ScrollbarAlwaysOn); - } - - if (hasVerticalScrollbar != scrollsVertically) { - m_data->setHasVerticalScrollbar(scrollsVertically); - hasVerticalScrollbar = scrollsVertically; - } - - if (hasHorizontalScrollbar != scrollsHorizontally) { - m_data->setHasHorizontalScrollbar(scrollsHorizontally); - hasHorizontalScrollbar = scrollsHorizontally; - } - } - - // Set up the range (and page step/line step). - IntSize maxScrollPosition(contentsWidth() - visibleWidth(), contentsHeight() - visibleHeight()); - IntSize scroll = desiredOffset.shrunkTo(maxScrollPosition); - scroll.clampNegativeToZero(); - - if (m_data->m_hBar) { - int clientWidth = visibleWidth(); - m_data->m_hBar->setEnabled(contentsWidth() > clientWidth); - int pageStep = (clientWidth - PAGE_KEEP); - if (pageStep < 0) pageStep = clientWidth; - IntRect oldRect(m_data->m_hBar->frameGeometry()); - IntRect hBarRect = IntRect(0, - height() - m_data->m_hBar->height(), - width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0), - m_data->m_hBar->height()); - m_data->m_hBar->setRect(hBarRect); - if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_hBar->frameGeometry()) - m_data->m_hBar->invalidate(); - - if (m_data->m_scrollbarsSuppressed) - m_data->m_hBar->setSuppressInvalidation(true); - m_data->m_hBar->setSteps(LINE_STEP, pageStep); - m_data->m_hBar->setProportion(clientWidth, contentsWidth()); - m_data->m_hBar->setValue(scroll.width()); - if (m_data->m_scrollbarsSuppressed) - m_data->m_hBar->setSuppressInvalidation(false); - } - - if (m_data->m_vBar) { - int clientHeight = visibleHeight(); - m_data->m_vBar->setEnabled(contentsHeight() > clientHeight); - int pageStep = (clientHeight - PAGE_KEEP); - if (pageStep < 0) pageStep = clientHeight; - IntRect oldRect(m_data->m_vBar->frameGeometry()); - IntRect vBarRect = IntRect(width() - m_data->m_vBar->width(), - 0, - m_data->m_vBar->width(), - height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0)); - m_data->m_vBar->setRect(vBarRect); - if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_vBar->frameGeometry()) - m_data->m_vBar->invalidate(); - - if (m_data->m_scrollbarsSuppressed) - m_data->m_vBar->setSuppressInvalidation(true); - m_data->m_vBar->setSteps(LINE_STEP, pageStep); - m_data->m_vBar->setProportion(clientHeight, contentsHeight()); - m_data->m_vBar->setValue(scroll.height()); - if (m_data->m_scrollbarsSuppressed) - m_data->m_vBar->setSuppressInvalidation(false); - } - - if (oldHasVertical != (m_data->m_vBar != 0) || oldHasHorizontal != (m_data->m_hBar != 0)) - geometryChanged(); - - // See if our offset has changed in a situation where we might not have scrollbars. - // This can happen when editing a body with overflow:hidden and scrolling to reveal selection. - // It can also happen when maximizing a window that has scrollbars (but the new maximized result - // does not). - IntSize scrollDelta = scroll - m_data->m_scrollOffset; - if (scrollDelta != IntSize()) { - m_data->m_scrollOffset = scroll; - m_data->scrollBackingStore(scrollDelta); - } - - m_data->m_inUpdateScrollbars = false; -} - -PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent) -{ - IntPoint viewPoint = convertFromContainingWindow(mouseEvent.pos()); - if (m_data->m_hBar && m_data->m_hBar->frameGeometry().contains(viewPoint)) - return m_data->m_hBar.get(); - if (m_data->m_vBar && m_data->m_vBar->frameGeometry().contains(viewPoint)) - return m_data->m_vBar.get(); - return 0; -} - -void ScrollView::addChild(Widget* child) -{ - child->setParent(this); - child->setContainingWindow(containingWindow()); - m_data->m_children.add(child); -} - -void ScrollView::removeChild(Widget* child) -{ - child->setParent(0); - m_data->m_children.remove(child); -} - -void ScrollView::paint(GraphicsContext* context, const IntRect& rect) -{ - // FIXME: This code is here so we don't have to fork FrameView.h/.cpp. - // In the end, FrameView should just merge with ScrollView. - ASSERT(isFrameView()); - - if (context->paintingDisabled() && !context->updatingControlTints()) - return; - - IntRect documentDirtyRect = rect; - documentDirtyRect.intersect(frameGeometry()); - - context->save(); - - context->translate(x(), y()); - documentDirtyRect.move(-x(), -y()); - - context->translate(-contentsX(), -contentsY()); - documentDirtyRect.move(contentsX(), contentsY()); - - context->clip(enclosingIntRect(visibleContentRect())); - - static_cast<const FrameView*>(this)->frame()->paint(context, documentDirtyRect); - - context->restore(); - - // Now paint the scrollbars. - if (!m_data->m_scrollbarsSuppressed && (m_data->m_hBar || m_data->m_vBar)) { - context->save(); - IntRect scrollViewDirtyRect = rect; - scrollViewDirtyRect.intersect(frameGeometry()); - context->translate(x(), y()); - scrollViewDirtyRect.move(-x(), -y()); - if (m_data->m_hBar) - m_data->m_hBar->paint(context, scrollViewDirtyRect); - if (m_data->m_vBar) - m_data->m_vBar->paint(context, scrollViewDirtyRect); - - // Fill the scroll corner with white. - IntRect hCorner; - if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) { - hCorner = IntRect(m_data->m_hBar->width(), - height() - m_data->m_hBar->height(), - width() - m_data->m_hBar->width(), - m_data->m_hBar->height()); - if (hCorner.intersects(scrollViewDirtyRect)) - context->fillRect(hCorner, Color::white); - } - - if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) { - IntRect vCorner(width() - m_data->m_vBar->width(), - m_data->m_vBar->height(), - m_data->m_vBar->width(), - height() - m_data->m_vBar->height()); - if (vCorner != hCorner && vCorner.intersects(scrollViewDirtyRect)) - context->fillRect(vCorner, Color::white); - } - - context->restore(); - } -} - -void ScrollView::themeChanged() -{ - PlatformScrollbar::themeChanged(); - theme()->themeChanged(); - invalidate(); -} - -void ScrollView::wheelEvent(PlatformWheelEvent& e) -{ - if (!m_data->allowsScrolling()) - return; - - // Determine how much we want to scroll. If we can move at all, we will accept the event. - IntSize maxScrollDelta = maximumScroll(); - if ((e.deltaX() < 0 && maxScrollDelta.width() > 0) || - (e.deltaX() > 0 && scrollOffset().width() > 0) || - (e.deltaY() < 0 && maxScrollDelta.height() > 0) || - (e.deltaY() > 0 && scrollOffset().height() > 0)) { - e.accept(); - scrollBy(-e.deltaX() * LINE_STEP, -e.deltaY() * LINE_STEP); - } -} - -HashSet<Widget*>* ScrollView::children() -{ - return &(m_data->m_children); -} - -void ScrollView::geometryChanged() const -{ - HashSet<Widget*>::const_iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::const_iterator current = m_data->m_children.begin(); current != end; ++current) - (*current)->geometryChanged(); -} - -bool ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity) -{ - if (direction == ScrollUp || direction == ScrollDown) { - if (m_data->m_vBar) - return m_data->m_vBar->scroll(direction, granularity); - } else { - if (m_data->m_hBar) - return m_data->m_hBar->scroll(direction, granularity); - } - return false; -} - -IntRect ScrollView::windowResizerRect() -{ - ASSERT(isFrameView()); - const FrameView* frameView = static_cast<const FrameView*>(this); - Page* page = frameView->frame() ? frameView->frame()->page() : 0; - if (!page) - return IntRect(); - return page->chrome()->windowResizerRect(); -} - -bool ScrollView::resizerOverlapsContent() const -{ - return !m_data->m_scrollbarsAvoidingResizer; -} - -void ScrollView::adjustOverlappingScrollbarCount(int overlapDelta) -{ - int oldCount = m_data->m_scrollbarsAvoidingResizer; - m_data->m_scrollbarsAvoidingResizer += overlapDelta; - if (parent() && parent()->isFrameView()) - static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(overlapDelta); - else if (!m_data->m_scrollbarsSuppressed) { - // If we went from n to 0 or from 0 to n and we're the outermost view, - // we need to invalidate the windowResizerRect(), since it will now need to paint - // differently. - if (oldCount > 0 && m_data->m_scrollbarsAvoidingResizer == 0 || - oldCount == 0 && m_data->m_scrollbarsAvoidingResizer > 0) - invalidateRect(windowResizerRect()); - } -} - -void ScrollView::setParent(ScrollView* parentView) -{ - if (!parentView && m_data->m_scrollbarsAvoidingResizer && parent() && parent()->isFrameView()) - static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(false); - Widget::setParent(parentView); -} - -void ScrollView::attachToWindow() -{ - if (m_data->m_attachedToWindow) - return; - - m_data->m_attachedToWindow = true; - - if (m_data->m_visible) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->attachToWindow(); - } -} - -void ScrollView::detachFromWindow() -{ - if (!m_data->m_attachedToWindow) - return; - - if (m_data->m_visible) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->detachFromWindow(); - } - - m_data->m_attachedToWindow = false; -} - -void ScrollView::show() -{ - if (!m_data->m_visible) { - m_data->m_visible = true; - if (isAttachedToWindow()) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->attachToWindow(); - } - } - - Widget::show(); -} - -void ScrollView::hide() -{ - if (m_data->m_visible) { - if (isAttachedToWindow()) { - HashSet<Widget*>::iterator end = m_data->m_children.end(); - for (HashSet<Widget*>::iterator it = m_data->m_children.begin(); it != end; ++it) - (*it)->detachFromWindow(); - } - m_data->m_visible = false; - } - - Widget::hide(); -} - -bool ScrollView::isAttachedToWindow() const -{ - return m_data->m_attachedToWindow; -} - -void ScrollView::addToDirtyRegion(const IntRect& containingWindowRect) -{ - ASSERT(isFrameView()); - const FrameView* frameView = static_cast<const FrameView*>(this); - Page* page = frameView->frame() ? frameView->frame()->page() : 0; - if (!page) - return; - page->chrome()->addToDirtyRegion(containingWindowRect); -} - -void ScrollView::scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect) -{ - ASSERT(isFrameView()); - const FrameView* frameView = static_cast<const FrameView*>(this); - Page* page = frameView->frame() ? frameView->frame()->page() : 0; - if (!page) - return; - page->chrome()->scrollBackingStore(dx, dy, scrollViewRect, clipRect); -} - -void ScrollView::updateBackingStore() -{ - ASSERT(isFrameView()); - const FrameView* frameView = static_cast<const FrameView*>(this); - Page* page = frameView->frame() ? frameView->frame()->page() : 0; - if (!page) - return; - page->chrome()->updateBackingStore(); -} - -void ScrollView::setAllowsScrolling(bool flag) -{ - m_data->setAllowsScrolling(flag); -} - -bool ScrollView::allowsScrolling() const -{ - return m_data->allowsScrolling(); -} - -bool ScrollView::inWindow() const -{ - // Needed for back/forward cache. - notImplemented(); - return true; -} - -} // namespace WebCore diff --git a/WebCore/platform/win/ScrollbarThemeSafari.cpp b/WebCore/platform/win/ScrollbarThemeSafari.cpp new file mode 100644 index 0000000..06a6533 --- /dev/null +++ b/WebCore/platform/win/ScrollbarThemeSafari.cpp @@ -0,0 +1,257 @@ +/* + * 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 "ScrollbarThemeSafari.h" + +#if USE(SAFARI_THEME) + +#include "GraphicsContext.h" +#include "IntRect.h" +#include "Page.h" +#include "PlatformMouseEvent.h" +#include "Scrollbar.h" +#include "ScrollbarClient.h" +#include "ScrollbarThemeWin.h" +#include "Settings.h" +#include "SoftLinking.h" + +#include <CoreGraphics/CoreGraphics.h> + +// If you have an empty placeholder SafariThemeConstants.h, then include SafariTheme.h +// This is a workaround until a version of WebKitSupportLibrary is released with an updated SafariThemeConstants.h +#include <SafariTheme/SafariThemeConstants.h> +#ifndef SafariThemeConstants_h +#include <SafariTheme/SafariTheme.h> +#endif + +// FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow. + +using namespace std; + +namespace WebCore { + +using namespace SafariTheme; + +ScrollbarTheme* ScrollbarTheme::nativeTheme() +{ + static ScrollbarThemeSafari safariTheme; + static ScrollbarThemeWin windowsTheme; + if (Settings::shouldPaintNativeControls()) + return &windowsTheme; + return &safariTheme; +} + +// FIXME: Get these numbers from CoreUI. +static int cScrollbarThickness[] = { 15, 11 }; +static int cRealButtonLength[] = { 28, 21 }; +static int cButtonInset[] = { 14, 11 }; +static int cButtonHitInset[] = { 3, 2 }; +// cRealButtonLength - cButtonInset +static int cButtonLength[] = { 14, 10 }; +static int cThumbMinLength[] = { 26, 20 }; + +#if !defined(NDEBUG) && defined(USE_DEBUG_SAFARI_THEME) +SOFT_LINK_DEBUG_LIBRARY(SafariTheme) +#else +SOFT_LINK_LIBRARY(SafariTheme) +#endif + +SOFT_LINK(SafariTheme, paintThemePart, void, __stdcall, + (ThemePart part, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state), + (part, context, rect, size, state)) + +static ScrollbarControlState scrollbarControlStateFromThemeState(ThemeControlState state) +{ + ScrollbarControlState s = 0; + if (state & ActiveState) + s |= ActiveScrollbarState; + if (state & EnabledState) + s |= EnabledScrollbarState; + if (state & PressedState) + s |= PressedScrollbarState; + return s; +} + +ScrollbarThemeSafari::~ScrollbarThemeSafari() +{ +} + +int ScrollbarThemeSafari::scrollbarThickness(ScrollbarControlSize controlSize) +{ + return cScrollbarThickness[controlSize]; +} + +bool ScrollbarThemeSafari::hasButtons(Scrollbar* scrollbar) +{ + return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? + scrollbar->width() : + scrollbar->height()) >= 2 * (cRealButtonLength[scrollbar->controlSize()] - cButtonHitInset[scrollbar->controlSize()]); +} + +bool ScrollbarThemeSafari::hasThumb(Scrollbar* scrollbar) +{ + return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? + scrollbar->width() : + scrollbar->height()) >= 2 * cButtonInset[scrollbar->controlSize()] + cThumbMinLength[scrollbar->controlSize()] + 1; +} + +static IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start) +{ + IntRect paintRect(buttonRect); + if (orientation == HorizontalScrollbar) { + paintRect.setWidth(cRealButtonLength[controlSize]); + if (!start) + paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - buttonRect.width())); + } else { + paintRect.setHeight(cRealButtonLength[controlSize]); + if (!start) + paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - buttonRect.height())); + } + + return paintRect; +} + +IntRect ScrollbarThemeSafari::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) +{ + IntRect result; + + // Windows just has single arrows. + if (part == BackButtonEndPart) + return result; + + int thickness = scrollbarThickness(scrollbar->controlSize()); + if (scrollbar->orientation() == HorizontalScrollbar) + result = IntRect(scrollbar->x(), scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness); + else + result = IntRect(scrollbar->x(), scrollbar->y(), thickness, cButtonLength[scrollbar->controlSize()]); + if (painting) + return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), true); + return result; +} + +IntRect ScrollbarThemeSafari::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) +{ + IntRect result; + + // Windows just has single arrows. + if (part == ForwardButtonStartPart) + return result; + + int thickness = scrollbarThickness(scrollbar->controlSize()); + if (scrollbar->orientation() == HorizontalScrollbar) + result = IntRect(scrollbar->x() + scrollbar->width() - cButtonLength[scrollbar->controlSize()], scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness); + else + result = IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - cButtonLength[scrollbar->controlSize()], thickness, cButtonLength[scrollbar->controlSize()]); + if (painting) + return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), false); + return result; +} + +static IntRect trackRepaintRect(const IntRect& trackRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize) +{ + IntRect paintRect(trackRect); + if (orientation == HorizontalScrollbar) + paintRect.inflateX(cButtonLength[controlSize]); + else + paintRect.inflateY(cButtonLength[controlSize]); + + return paintRect; +} + +IntRect ScrollbarThemeSafari::trackRect(Scrollbar* scrollbar, bool painting) +{ + if (painting || !hasButtons(scrollbar)) + return scrollbar->frameRect(); + + IntRect result; + int thickness = scrollbarThickness(scrollbar->controlSize()); + if (scrollbar->orientation() == HorizontalScrollbar) + return IntRect(scrollbar->x() + cButtonLength[scrollbar->controlSize()], scrollbar->y(), scrollbar->width() - 2 * cButtonLength[scrollbar->controlSize()], thickness); + return IntRect(scrollbar->x(), scrollbar->y() + cButtonLength[scrollbar->controlSize()], thickness, scrollbar->height() - 2 * cButtonLength[scrollbar->controlSize()]); +} + +int ScrollbarThemeSafari::minimumThumbLength(Scrollbar* scrollbar) +{ + return cThumbMinLength[scrollbar->controlSize()]; +} + +bool ScrollbarThemeSafari::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt) +{ + return evt.shiftKey() && evt.button() == LeftButton; +} + +void ScrollbarThemeSafari::paintTrackBackground(GraphicsContext* graphicsContext, Scrollbar* scrollbar, const IntRect& trackRect) +{ + if (!SafariThemeLibrary()) + return; + NSControlSize size = scrollbar->controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize; + ThemeControlState state = 0; + if (scrollbar->client()->isActive()) + state |= ActiveState; + if (hasButtons(scrollbar)) + state |= EnabledState; + paintThemePart(scrollbar->orientation() == VerticalScrollbar ? VScrollTrackPart : HScrollTrackPart, graphicsContext->platformContext(), trackRect, size, state); +} + +void ScrollbarThemeSafari::paintButton(GraphicsContext* graphicsContext, Scrollbar* scrollbar, const IntRect& buttonRect, ScrollbarPart part) +{ + if (!SafariThemeLibrary()) + return; + NSControlSize size = scrollbar->controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize; + ThemeControlState state = 0; + if (scrollbar->client()->isActive()) + state |= ActiveState; + if (hasButtons(scrollbar)) + state |= EnabledState; + if (scrollbar->pressedPart() == part) + state |= PressedState; + if (part == BackButtonStartPart) + paintThemePart(scrollbar->orientation() == VerticalScrollbar ? ScrollUpArrowPart : ScrollLeftArrowPart, graphicsContext->platformContext(), + buttonRect, size, state); + else if (part == ForwardButtonEndPart) + paintThemePart(scrollbar->orientation() == VerticalScrollbar ? ScrollDownArrowPart : ScrollRightArrowPart, graphicsContext->platformContext(), + buttonRect, size, state); +} + +void ScrollbarThemeSafari::paintThumb(GraphicsContext* graphicsContext, Scrollbar* scrollbar, const IntRect& thumbRect) +{ + if (!SafariThemeLibrary()) + return; + NSControlSize size = scrollbar->controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize; + ThemeControlState state = 0; + if (scrollbar->client()->isActive()) + state |= ActiveState; + if (hasThumb(scrollbar)) + state |= EnabledState; + if (scrollbar->pressedPart() == ThumbPart) + state |= PressedState; + paintThemePart(scrollbar->orientation() == VerticalScrollbar ? VScrollThumbPart : HScrollThumbPart, graphicsContext->platformContext(), + thumbRect, size, state); +} + +} + +#endif diff --git a/WebCore/platform/win/ScrollbarThemeSafari.h b/WebCore/platform/win/ScrollbarThemeSafari.h new file mode 100644 index 0000000..f039379 --- /dev/null +++ b/WebCore/platform/win/ScrollbarThemeSafari.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScrollbarThemeSafari_h +#define ScrollbarThemeSafari_h + +#if USE(SAFARI_THEME) + +#include "ScrollbarThemeComposite.h" + +namespace WebCore { + +class ScrollbarThemeSafari : public ScrollbarThemeComposite { +public: + virtual ~ScrollbarThemeSafari(); + + virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + + virtual bool supportsControlTints() const { return true; } + +protected: + virtual bool hasButtons(Scrollbar*); + virtual bool hasThumb(Scrollbar*); + + virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect trackRect(Scrollbar*, bool painting = false); + + virtual int minimumThumbLength(Scrollbar*); + + virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&); + + virtual void paintTrackBackground(GraphicsContext*, Scrollbar*, const IntRect&); + virtual void paintButton(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart); + virtual void paintThumb(GraphicsContext*, Scrollbar*, const IntRect&); +}; + +} +#endif + +#endif diff --git a/WebCore/platform/win/ScrollbarThemeWin.cpp b/WebCore/platform/win/ScrollbarThemeWin.cpp new file mode 100644 index 0000000..e13d893 --- /dev/null +++ b/WebCore/platform/win/ScrollbarThemeWin.cpp @@ -0,0 +1,363 @@ +/* + * 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 "ScrollbarThemeWin.h" + +#include "GraphicsContext.h" +#include "PlatformMouseEvent.h" +#include "Scrollbar.h" +#include "SoftLinking.h" + +// Generic state constants +#define TS_NORMAL 1 +#define TS_HOVER 2 +#define TS_ACTIVE 3 +#define TS_DISABLED 4 + +#define SP_BUTTON 1 +#define SP_THUMBHOR 2 +#define SP_THUMBVERT 3 +#define SP_TRACKSTARTHOR 4 +#define SP_TRACKENDHOR 5 +#define SP_TRACKSTARTVERT 6 +#define SP_TRACKENDVERT 7 +#define SP_GRIPPERHOR 8 +#define SP_GRIPPERVERT 9 + +#define TS_UP_BUTTON 0 +#define TS_DOWN_BUTTON 4 +#define TS_LEFT_BUTTON 8 +#define TS_RIGHT_BUTTON 12 +#define TS_UP_BUTTON_HOVER 17 +#define TS_DOWN_BUTTON_HOVER 18 +#define TS_LEFT_BUTTON_HOVER 19 +#define TS_RIGHT_BUTTON_HOVER 20 + +using namespace std; + +namespace WebCore { + +static HANDLE scrollbarTheme; +static bool haveTheme; +static bool runningVista; + +// FIXME: Refactor the soft-linking code so that it can be shared with RenderThemeWin +SOFT_LINK_LIBRARY(uxtheme) +SOFT_LINK(uxtheme, OpenThemeData, HANDLE, WINAPI, (HWND hwnd, LPCWSTR pszClassList), (hwnd, pszClassList)) +SOFT_LINK(uxtheme, CloseThemeData, HRESULT, WINAPI, (HANDLE hTheme), (hTheme)) +SOFT_LINK(uxtheme, DrawThemeBackground, HRESULT, WINAPI, (HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT* pRect, const RECT* pClipRect), (hTheme, hdc, iPartId, iStateId, pRect, pClipRect)) +SOFT_LINK(uxtheme, IsThemeActive, BOOL, WINAPI, (), ()) +SOFT_LINK(uxtheme, IsThemeBackgroundPartiallyTransparent, BOOL, WINAPI, (HANDLE hTheme, int iPartId, int iStateId), (hTheme, iPartId, iStateId)) + +static bool isRunningOnVistaOrLater() +{ + static bool os = false; + static bool initialized = false; + if (!initialized) { + OSVERSIONINFOEX vi = {sizeof(vi), 0}; + GetVersionEx((OSVERSIONINFO*)&vi); + + // NOTE: This does not work under a debugger - Vista shims Visual Studio, + // making it believe it is xpsp2, which is inherited by debugged applications + os = vi.dwMajorVersion >= 6; + initialized = true; + } + return os; +} + +static void checkAndInitScrollbarTheme() +{ + if (uxthemeLibrary() && !scrollbarTheme) + scrollbarTheme = OpenThemeData(0, L"Scrollbar"); + haveTheme = scrollbarTheme && IsThemeActive(); +} + +#if !USE(SAFARI_THEME) +ScrollbarTheme* ScrollbarTheme::nativeTheme() +{ + static ScrollbarThemeWin winTheme; + return &winTheme; +} +#endif + +ScrollbarThemeWin::ScrollbarThemeWin() +{ + static bool initialized; + if (!initialized) { + initialized = true; + checkAndInitScrollbarTheme(); + runningVista = isRunningOnVistaOrLater(); + } +} + +ScrollbarThemeWin::~ScrollbarThemeWin() +{ +} + +int ScrollbarThemeWin::scrollbarThickness(ScrollbarControlSize) +{ + static int thickness; + if (!thickness) + thickness = ::GetSystemMetrics(SM_CXVSCROLL); + return thickness; +} + +void ScrollbarThemeWin::themeChanged() +{ + if (haveTheme) + CloseThemeData(scrollbarTheme); +} + +bool ScrollbarThemeWin::invalidateOnMouseEnterExit() +{ + return runningVista; +} + +bool ScrollbarThemeWin::hasThumb(Scrollbar* scrollbar) +{ + return thumbLength(scrollbar) > 0; +} + +IntRect ScrollbarThemeWin::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + // Windows just has single arrows. + if (part == BackButtonEndPart) + return IntRect(); + + // Our desired rect is essentially 17x17. + + // Our actual rect will shrink to half the available space when + // we have < 34 pixels left. This allows the scrollbar + // to scale down and function even at tiny sizes. + int thickness = scrollbarThickness(); + if (scrollbar->orientation() == HorizontalScrollbar) + return IntRect(scrollbar->x(), scrollbar->y(), + scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : thickness, thickness); + return IntRect(scrollbar->x(), scrollbar->y(), + thickness, scrollbar->height() < 2 * thickness ? scrollbar->height() / 2 : thickness); +} + +IntRect ScrollbarThemeWin::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool) +{ + // Windows just has single arrows. + if (part == ForwardButtonStartPart) + return IntRect(); + + // Our desired rect is essentially 17x17. + + // Our actual rect will shrink to half the available space when + // we have < 34 pixels left. This allows the scrollbar + // to scale down and function even at tiny sizes. + int thickness = scrollbarThickness(); + if (scrollbar->orientation() == HorizontalScrollbar) { + int w = scrollbar->width() < 2 * thickness ? scrollbar->width() / 2 : thickness; + return IntRect(scrollbar->x() + scrollbar->width() - w, scrollbar->y(), w, thickness); + } + + int h = scrollbar->height() < 2 * thickness ? scrollbar->height() / 2 : thickness; + return IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - h, thickness, h); +} + +IntRect ScrollbarThemeWin::trackRect(Scrollbar* scrollbar, bool) +{ + int thickness = scrollbarThickness(); + if (scrollbar->orientation() == HorizontalScrollbar) { + if (scrollbar->width() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x() + thickness, scrollbar->y(), scrollbar->width() - 2 * thickness, thickness); + } + if (scrollbar->height() < 2 * thickness) + return IntRect(); + return IntRect(scrollbar->x(), scrollbar->y() + thickness, thickness, scrollbar->height() - 2 * thickness); +} + +void ScrollbarThemeWin::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) +{ + // Just assume a forward track part. We only paint the track as a single piece when there is no thumb. + if (!hasThumb(scrollbar)) + paintTrackPiece(context, scrollbar, rect, ForwardTrackPart); +} + +void ScrollbarThemeWin::paintTrackPiece(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType) +{ + checkAndInitScrollbarTheme(); + + bool start = partType == BackTrackPart; + int part; + if (scrollbar->orientation() == HorizontalScrollbar) + part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR; + else + part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT; + + int state; + if (!scrollbar->enabled()) + state = TS_DISABLED; + else if ((scrollbar->hoveredPart() == BackTrackPart && start) || + (scrollbar->hoveredPart() == ForwardTrackPart && !start)) + state = (scrollbar->pressedPart() == scrollbar->hoveredPart() ? TS_ACTIVE : TS_HOVER); + else + state = TS_NORMAL; + + bool alphaBlend = false; + if (scrollbarTheme) + alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state); + HDC hdc = context->getWindowsContext(rect, alphaBlend); + RECT themeRect(rect); + if (scrollbarTheme) + DrawThemeBackground(scrollbarTheme, hdc, part, state, &themeRect, 0); + else { + DWORD color3DFace = ::GetSysColor(COLOR_3DFACE); + DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR); + DWORD colorWindow = ::GetSysColor(COLOR_WINDOW); + if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar)) + ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1)); + else { + static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }; + HBITMAP patternBitmap = ::CreateBitmap(8, 8, 1, 1, patternBits); + HBRUSH brush = ::CreatePatternBrush(patternBitmap); + SaveDC(hdc); + ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT)); + ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE)); + ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL); + ::SelectObject(hdc, brush); + ::FillRect(hdc, &themeRect, brush); + ::RestoreDC(hdc, -1); + ::DeleteObject(brush); + ::DeleteObject(patternBitmap); + } + } + context->releaseWindowsContext(hdc, rect, alphaBlend); +} + +void ScrollbarThemeWin::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) +{ + checkAndInitScrollbarTheme(); + + bool start = (part == BackButtonStartPart); + int xpState = 0; + int classicState = 0; + if (scrollbar->orientation() == HorizontalScrollbar) + xpState = start ? TS_LEFT_BUTTON : TS_RIGHT_BUTTON; + else + xpState = start ? TS_UP_BUTTON : TS_DOWN_BUTTON; + classicState = xpState / 4; + + if (!scrollbar->enabled()) { + xpState += TS_DISABLED; + classicState |= DFCS_INACTIVE; + } else if ((scrollbar->hoveredPart() == BackButtonStartPart && start) || + (scrollbar->hoveredPart() == ForwardButtonEndPart && !start)) { + if (scrollbar->pressedPart() == scrollbar->hoveredPart()) { + xpState += TS_ACTIVE; + classicState |= DFCS_PUSHED | DFCS_FLAT; + } else + xpState += TS_HOVER; + } else { + if (scrollbar->hoveredPart() == NoPart || !runningVista) + xpState += TS_NORMAL; + else { + if (scrollbar->orientation() == HorizontalScrollbar) + xpState = start ? TS_LEFT_BUTTON_HOVER : TS_RIGHT_BUTTON_HOVER; + else + xpState = start ? TS_UP_BUTTON_HOVER : TS_DOWN_BUTTON_HOVER; + } + } + + bool alphaBlend = false; + if (scrollbarTheme) + alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BUTTON, xpState); + HDC hdc = context->getWindowsContext(rect, alphaBlend); + + RECT themeRect(rect); + if (scrollbarTheme) + DrawThemeBackground(scrollbarTheme, hdc, SP_BUTTON, xpState, &themeRect, 0); + else + ::DrawFrameControl(hdc, &themeRect, DFC_SCROLL, classicState); + context->releaseWindowsContext(hdc, rect, alphaBlend); +} + +static IntRect gripperRect(int thickness, const IntRect& thumbRect) +{ + // Center in the thumb. + int gripperThickness = thickness / 2; + return IntRect(thumbRect.x() + (thumbRect.width() - gripperThickness) / 2, + thumbRect.y() + (thumbRect.height() - gripperThickness) / 2, + gripperThickness, gripperThickness); +} + +static void paintGripper(Scrollbar* scrollbar, HDC hdc, const IntRect& rect) +{ + if (!scrollbarTheme) + return; // Classic look has no gripper. + + int state; + if (!scrollbar->enabled()) + state = TS_DISABLED; + else if (scrollbar->pressedPart() == ThumbPart) + state = TS_ACTIVE; // Thumb always stays active once pressed. + else if (scrollbar->hoveredPart() == ThumbPart) + state = TS_HOVER; + else + state = TS_NORMAL; + + RECT themeRect(rect); + DrawThemeBackground(scrollbarTheme, hdc, scrollbar->orientation() == HorizontalScrollbar ? SP_GRIPPERHOR : SP_GRIPPERVERT, state, &themeRect, 0); +} + +void ScrollbarThemeWin::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) +{ + checkAndInitScrollbarTheme(); + + int state; + if (!scrollbar->enabled()) + state = TS_DISABLED; + else if (scrollbar->pressedPart() == ThumbPart) + state = TS_ACTIVE; // Thumb always stays active once pressed. + else if (scrollbar->hoveredPart() == ThumbPart) + state = TS_HOVER; + else + state = TS_NORMAL; + + bool alphaBlend = false; + if (scrollbarTheme) + alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, scrollbar->orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state); + HDC hdc = context->getWindowsContext(rect, alphaBlend); + RECT themeRect(rect); + if (scrollbarTheme) { + DrawThemeBackground(scrollbarTheme, hdc, scrollbar->orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRect, 0); + paintGripper(scrollbar, hdc, gripperRect(scrollbarThickness(), rect)); + } else + ::DrawEdge(hdc, &themeRect, EDGE_RAISED, BF_RECT | BF_MIDDLE); + context->releaseWindowsContext(hdc, rect, alphaBlend); +} + +bool ScrollbarThemeWin::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt) +{ + return evt.shiftKey() && evt.button() == LeftButton; +} + +} + diff --git a/WebCore/platform/win/ScrollbarThemeWin.h b/WebCore/platform/win/ScrollbarThemeWin.h new file mode 100644 index 0000000..92e2523 --- /dev/null +++ b/WebCore/platform/win/ScrollbarThemeWin.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScrollbarThemeWin_h +#define ScrollbarThemeWin_h + +#include "ScrollbarThemeComposite.h" + +namespace WebCore { + +class ScrollbarThemeWin : public ScrollbarThemeComposite { +public: + ScrollbarThemeWin(); + virtual ~ScrollbarThemeWin(); + + virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + + virtual void themeChanged(); + + virtual bool invalidateOnMouseEnterExit(); + +protected: + virtual bool hasButtons(Scrollbar*) { return true; } + virtual bool hasThumb(Scrollbar*); + + virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect trackRect(Scrollbar*, bool painting = false); + + virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&); + + virtual void paintTrackBackground(GraphicsContext*, Scrollbar*, const IntRect&); + virtual void paintTrackPiece(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart); + virtual void paintButton(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart); + virtual void paintThumb(GraphicsContext*, Scrollbar*, const IntRect&); +}; + +} +#endif diff --git a/WebCore/platform/win/SharedBufferWin.cpp b/WebCore/platform/win/SharedBufferWin.cpp index 99422f2..ce93402 100644 --- a/WebCore/platform/win/SharedBufferWin.cpp +++ b/WebCore/platform/win/SharedBufferWin.cpp @@ -50,7 +50,7 @@ PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& fi if (_fstat64(_fileno(fileDescriptor), &fileStat)) goto exit; - result = new SharedBuffer(); + result = SharedBuffer::create(); result->m_buffer.resize(fileStat.st_size); if (result->m_buffer.size() != fileStat.st_size) { result = 0; diff --git a/WebCore/platform/win/SharedTimerWin.cpp b/WebCore/platform/win/SharedTimerWin.cpp index 8ff7734..b611659 100644 --- a/WebCore/platform/win/SharedTimerWin.cpp +++ b/WebCore/platform/win/SharedTimerWin.cpp @@ -39,6 +39,21 @@ #endif #include <windows.h> +#include <mmsystem.h> + +// These aren't in winuser.h with the MSVS 2003 Platform SDK, +// so use default values in that case. +#ifndef USER_TIMER_MINIMUM +#define USER_TIMER_MINIMUM 0x0000000A +#endif + +#ifndef USER_TIMER_MAXIMUM +#define USER_TIMER_MAXIMUM 0x7FFFFFFF +#endif + +#ifndef QS_RAWINPUT +#define QS_RAWINPUT 0x0400 +#endif #if PLATFORM(WIN) #include "PluginView.h" @@ -51,9 +66,22 @@ static void (*sharedTimerFiredFunction)(); static HWND timerWindowHandle = 0; static UINT timerFiredMessage = 0; -const LPCWSTR kTimerWindowClassName = L"TimerWindowClass"; +static HANDLE timerQueue; +static HANDLE timer; +static Mutex timerMutex; +static bool highResTimerActive; static bool processingCustomTimerMessage = false; -const int sharedTimerID = 1000; +static LONG pendingTimers; + +const LPCWSTR kTimerWindowClassName = L"TimerWindowClass"; +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) { @@ -69,13 +97,22 @@ LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPAR #endif if (message == timerFiredMessage) { + InterlockedExchange(&pendingTimers, 0); processingCustomTimerMessage = true; sharedTimerFiredFunction(); processingCustomTimerMessage = false; - } else if (message == WM_TIMER && wParam == sharedTimerID) - sharedTimerFiredFunction(); - else + } else if (message == WM_TIMER) { + if (wParam == sharedTimerID) { + KillTimer(timerWindowHandle, sharedTimerID); + sharedTimerFiredFunction(); + } else if (wParam == endHighResTimerID) { + KillTimer(timerWindowHandle, endHighResTimerID); + highResTimerActive = false; + timeEndPeriod(timerResolution); + } + } else return DefWindowProc(hWnd, message, wParam, lParam); + return 0; } @@ -102,6 +139,21 @@ void setSharedTimerFiredFunction(void (*f)()) sharedTimerFiredFunction = f; } +static void clearTimer() +{ + MutexLocker locker(timerMutex); + if (timerQueue && timer) + DeleteTimerQueueTimer(timerQueue, timer, 0); + timer = 0; +} + +static void NTAPI queueTimerProc(PVOID, BOOLEAN) +{ + clearTimer(); + if (InterlockedIncrement(&pendingTimers) == 1) + PostMessage(timerWindowHandle, timerFiredMessage, 0, 0); +} + void setSharedTimerFireTime(double fireTime) { ASSERT(sharedTimerFiredFunction); @@ -118,29 +170,54 @@ void setSharedTimerFireTime(double fireTime) intervalInMS = (unsigned)interval; } - if (timerID) { - KillTimer(0, timerID); - timerID = 0; + if (interval < highResolutionThresholdMsec) { + if (!highResTimerActive) { + highResTimerActive = true; + timeBeginPeriod(timerResolution); + } + SetTimer(timerWindowHandle, endHighResTimerID, stopHighResTimerInMsec, 0); } - // We don't allow nested PostMessages, since the custom messages will effectively starve - // painting and user input. (Win32 has a tri-level queue with application messages > - // user input > WM_PAINT/WM_TIMER.) - // In addition, if the queue contains input events that have been there since the last call to - // GetQueueStatus, PeekMessage or GetMessage we favor timers. initializeOffScreenTimerWindow(); - if (intervalInMS < USER_TIMER_MINIMUM && !processingCustomTimerMessage && - !LOWORD(::GetQueueStatus(QS_ALLINPUT))) { - // Windows SetTimer does not allow timeouts smaller than 10ms (USER_TIMER_MINIMUM) - PostMessage(timerWindowHandle, timerFiredMessage, 0, 0); + bool timerSet = false; + 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(); + MutexLocker locker(timerMutex); + if (timer) + timerSet = ChangeTimerQueueTimer(timerQueue, timer, intervalInMS, 0); + else + 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); } void stopSharedTimer() { + clearTimer(); if (timerID) { - KillTimer(0, timerID); + KillTimer(timerWindowHandle, timerID); timerID = 0; } } diff --git a/WebCore/platform/win/SystemTimeWin.cpp b/WebCore/platform/win/SystemTimeWin.cpp index 76f77ae..473e8de 100644 --- a/WebCore/platform/win/SystemTimeWin.cpp +++ b/WebCore/platform/win/SystemTimeWin.cpp @@ -26,39 +26,31 @@ #include "config.h" #include "SystemTime.h" -#include "NotImplemented.h" +#include <DateMath.h> #include <windows.h> +#if COMPILER(MINGW) +#include <float.h> +#define FLOAT_MAX FLT_MAX +#endif + namespace WebCore { double currentTime() { - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - - // As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a - // ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can - // prevent alignment faults on 64-bit Windows). - - ULARGE_INTEGER t; - memcpy(&t, &ft, sizeof(t)); - - // Windows file times are in 100s of nanoseconds. - // To convert to seconds, we have to divide by 10,000,000, which is more quickly - // done by multiplying by 0.0000001. - - // Between January 1, 1601 and January 1, 1970, there were 369 complete years, - // of which 89 were leap years (1700, 1800, and 1900 were not leap years). - // That is a total of 134774 days, which is 11644473600 seconds. - - return t.QuadPart * 0.0000001 - 11644473600.0; + // Call through to our high-resolution JSC time code, since calls like GetSystemTimeAsFileTime and ftime are only accurate within 15ms. + // This resolution can be improved with timeBeginPeriod/timeEndPeriod on Vista, but these calls don't + // improve the resolution of date/time getters (GetSystemTimeAsFileTime, ftime, etc.) on XP. + return JSC::getCurrentUTCTimeWithMicroseconds() * 0.001; } float userIdleTime() { - // Needed for back/forward cache. - notImplemented(); - return 0.0F; + LASTINPUTINFO lastInputInfo = {0}; + lastInputInfo.cbSize = sizeof(LASTINPUTINFO); + if (::GetLastInputInfo(&lastInputInfo)) + return (GetTickCount() - lastInputInfo.dwTime) * 0.001; // ::GetTickCount returns ms of uptime valid for up to 49.7 days. + return FLT_MAX; // return an arbitrarily high userIdleTime so that releasing pages from the page cache isn't postponed. } } diff --git a/WebCore/platform/win/TemporaryLinkStubs.cpp b/WebCore/platform/win/TemporaryLinkStubs.cpp index 4a8a093..80c8df0 100644 --- a/WebCore/platform/win/TemporaryLinkStubs.cpp +++ b/WebCore/platform/win/TemporaryLinkStubs.cpp @@ -25,7 +25,6 @@ #include "config.h" -#include "CachedPage.h" #include "NotImplemented.h" #include "SSLKeyGenerator.h" @@ -33,6 +32,6 @@ namespace WebCore { // <keygen> String signedPublicKeyAndChallengeString(unsigned, const String&, const KURL&) { notImplemented(); return String(); } -Vector<String> supportedKeySizes() { notImplemented(); return Vector<String>(); } +void getSupportedKeySizes(Vector<String>&) { notImplemented(); } -} +} // namespace WebCore diff --git a/WebCore/platform/win/ThreadConditionWin.cpp b/WebCore/platform/win/ThreadConditionWin.cpp deleted file mode 100644 index f2bdb78..0000000 --- a/WebCore/platform/win/ThreadConditionWin.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, 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. - * - * ============================================================================= - * Note: The implementation of condition variables under the Windows - * plaform was based on that of the excellent BOOST C++ library. It - * has been rewritten to fit in with the WebKit architecture and to - * use its coding conventions. - * ============================================================================= - * - * The Boost license is virtually identical to the Apple variation at the - * top of this file, but is included here for completeness: - * - * Boost Software License - Version 1.0 - August 17th, 2003 - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" -#include "Logging.h" -#include "Threading.h" -#include <limits> -#include <errno.h> - -namespace WebCore { - -static const long MaxSemaphoreCount = static_cast<long>(~0UL >> 1); - -ThreadCondition::ThreadCondition() -{ - m_condition.m_timedOut = 0; - m_condition.m_blocked = 0; - m_condition.m_waitingForRemoval = 0; - m_condition.m_gate = ::CreateSemaphore(0, 1, 1, 0); - m_condition.m_queue = ::CreateSemaphore(0, 0, MaxSemaphoreCount, 0); - m_condition.m_mutex = ::CreateMutex(0, 0, 0); - - if (!m_condition.m_gate || !m_condition.m_queue || !m_condition.m_mutex) { - if (m_condition.m_gate) - ::CloseHandle(m_condition.m_gate); - if (m_condition.m_queue) - ::CloseHandle(m_condition.m_queue); - if (m_condition.m_mutex) - ::CloseHandle(m_condition.m_mutex); - } -} - -ThreadCondition::~ThreadCondition() -{ - ::CloseHandle(m_condition.m_gate); - ::CloseHandle(m_condition.m_queue); - ::CloseHandle(m_condition.m_mutex); -} - -void ThreadCondition::wait(Mutex& mutex) -{ - PlatformMutex& cs = mutex.impl(); - - // Enter the wait state. - DWORD res = ::WaitForSingleObject(m_condition.m_gate, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - ++m_condition.m_blocked; - res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0); - ASSERT(res); - - ::LeaveCriticalSection(&cs.m_internalMutex); - - res = ::WaitForSingleObject(m_condition.m_queue, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - - res = ::WaitForSingleObject(m_condition.m_mutex, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - size_t wasWaiting = m_condition.m_waitingForRemoval; - size_t wasTimedOut = m_condition.m_timedOut; - if (wasWaiting != 0) { - if (--m_condition.m_waitingForRemoval == 0) { - if (m_condition.m_blocked != 0) { - res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0); // open m_gate - ASSERT(res); - wasWaiting = 0; - } - else if (m_condition.m_timedOut != 0) - m_condition.m_timedOut = 0; - } - } else if (++m_condition.m_timedOut == ((std::numeric_limits<unsigned>::max)() / 2)) { - // timeout occured, normalize the m_condition.m_timedOut count - // this may occur if many calls to wait with a timeout are made and - // no call to notify_* is made - res = ::WaitForSingleObject(m_condition.m_gate, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - m_condition.m_blocked -= m_condition.m_timedOut; - res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0); - ASSERT(res); - m_condition.m_timedOut = 0; - } - res = ::ReleaseMutex(m_condition.m_mutex); - ASSERT(res); - - if (wasWaiting == 1) { - for (/**/ ; wasTimedOut; --wasTimedOut) { - // better now than spurious later - res = ::WaitForSingleObject(m_condition.m_queue, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - } - res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0); - ASSERT(res); - } - - ::EnterCriticalSection (&cs.m_internalMutex); -} - -void ThreadCondition::signal() -{ - unsigned signals = 0; - - DWORD res = ::WaitForSingleObject(m_condition.m_mutex, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - - if (m_condition.m_waitingForRemoval != 0) { // the m_gate is already closed - if (m_condition.m_blocked == 0) { - res = ::ReleaseMutex(m_condition.m_mutex); - ASSERT(res); - return; - } - - ++m_condition.m_waitingForRemoval; - --m_condition.m_blocked; - - signals = 1; - } else { - res = ::WaitForSingleObject(m_condition.m_gate, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - if (m_condition.m_blocked > m_condition.m_timedOut) { - if (m_condition.m_timedOut != 0) { - m_condition.m_blocked -= m_condition.m_timedOut; - m_condition.m_timedOut = 0; - } - signals = m_condition.m_waitingForRemoval = 1; - --m_condition.m_blocked; - } else { - res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0); - ASSERT(res); - } - } - - res =::ReleaseMutex(m_condition.m_mutex); - ASSERT(res); - - if (signals) { - res = ::ReleaseSemaphore(m_condition.m_queue, signals, 0); - ASSERT(res); - } -} - -void ThreadCondition::broadcast() -{ - unsigned signals = 0; - - WORD res = ::WaitForSingleObject(m_condition.m_mutex, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - - if (m_condition.m_waitingForRemoval != 0) { // the m_gate is already closed - if (m_condition.m_blocked == 0) { - res = ::ReleaseMutex(m_condition.m_mutex); - ASSERT(res); - return; - } - - m_condition.m_waitingForRemoval += (signals = m_condition.m_blocked); - m_condition.m_blocked = 0; - } else { - res = ::WaitForSingleObject(m_condition.m_gate, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - if (m_condition.m_blocked > m_condition.m_timedOut) { - if (m_condition.m_timedOut != 0) { - m_condition.m_blocked -= m_condition.m_timedOut; - m_condition.m_timedOut = 0; - } - signals = m_condition.m_waitingForRemoval = m_condition.m_blocked; - m_condition.m_blocked = 0; - } else { - res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0); - ASSERT(res); - } - } - - res = ::ReleaseMutex(m_condition.m_mutex); - ASSERT(res); - - if (signals) { - res = ::ReleaseSemaphore(m_condition.m_queue, signals, 0); - ASSERT(res); - } -} - -} // namespace WebCore diff --git a/WebCore/platform/win/ThreadingWin.cpp b/WebCore/platform/win/ThreadingWin.cpp deleted file mode 100644 index 0da3d17..0000000 --- a/WebCore/platform/win/ThreadingWin.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 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. - * 3. Neither the name of Apple Computer, 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 "Logging.h" -#include "Page.h" -#include "Threading.h" -#include <errno.h> -#include <windows.h> -#include <wtf/HashMap.h> - -namespace WebCore { - -struct FunctionWithContext { - MainThreadFunction* function; - void* context; - FunctionWithContext(MainThreadFunction* f = 0, void* c = 0) : function(f), context(c) { } -}; - -typedef Vector<FunctionWithContext> FunctionQueue; - -static HWND threadingWindowHandle = 0; -static UINT threadingFiredMessage = 0; -const LPCWSTR kThreadingWindowClassName = L"ThreadingWindowClass"; -static bool processingCustomThreadingMessage = false; - -static Mutex& threadMapMutex() -{ - static Mutex mutex; - return mutex; -} - -static HashMap<DWORD, HANDLE>& threadMap() -{ - static HashMap<DWORD, HANDLE> map; - return map; -} - -static void storeThreadHandleByIdentifier(DWORD threadID, HANDLE threadHandle) -{ - MutexLocker locker(threadMapMutex()); - threadMap().add(threadID, threadHandle); -} - -static HANDLE threadHandleForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - return threadMap().get(id); -} - -static void clearThreadHandleForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - ASSERT(threadMap().contains(id)); - threadMap().remove(id); -} - -ThreadIdentifier createThread(ThreadFunction entryPoint, void* data) -{ - DWORD threadIdentifier = 0; - ThreadIdentifier threadID = 0; - HANDLE hEvent = ::CreateEvent(0, FALSE, FALSE, 0); - HANDLE threadHandle = ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)entryPoint, data, 0, &threadIdentifier); - if (!threadHandle) { - LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data); - return 0; - } - - threadID = static_cast<ThreadIdentifier>(threadIdentifier); - storeThreadHandleByIdentifier(threadIdentifier, threadHandle); - - LOG(Threading, "Created thread with thread id %u", threadID); - return threadID; -} - -int waitForThreadCompletion(ThreadIdentifier threadID, void** result) -{ - ASSERT(threadID); - - HANDLE threadHandle = threadHandleForIdentifier(threadID); - if (!threadHandle) - LOG_ERROR("ThreadIdentifier %u did not correspond to an active thread when trying to quit", threadID); - - DWORD joinResult = ::WaitForSingleObject(threadHandle, INFINITE); - if (joinResult == WAIT_FAILED) - LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID); - - ::CloseHandle(threadHandle); - clearThreadHandleForIdentifier(threadID); - - return joinResult; -} - -void detachThread(ThreadIdentifier threadID) -{ - ASSERT(threadID); - - HANDLE threadHandle = threadHandleForIdentifier(threadID); - if (threadHandle) - ::CloseHandle(threadHandle); - clearThreadHandleForIdentifier(threadID); -} - -ThreadIdentifier currentThread() -{ - return static_cast<ThreadIdentifier>(::GetCurrentThreadId()); -} - -static Mutex& functionQueueMutex() -{ - static Mutex staticFunctionQueueMutex; - return staticFunctionQueueMutex; -} - -static FunctionQueue& functionQueue() -{ - static FunctionQueue staticFunctionQueue; - return staticFunctionQueue; -} - -static void callFunctionsOnMainThread() -{ - FunctionQueue queueCopy; - { - MutexLocker locker(functionQueueMutex()); - queueCopy.swap(functionQueue()); - } - - LOG(Threading, "Calling %u functions on the main thread", queueCopy.size()); - for (unsigned i = 0; i < queueCopy.size(); ++i) - queueCopy[i].function(queueCopy[i].context); -} - -LRESULT CALLBACK ThreadingWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - if (message == threadingFiredMessage) { - processingCustomThreadingMessage = true; - callFunctionsOnMainThread(); - processingCustomThreadingMessage = false; - } else - return DefWindowProc(hWnd, message, wParam, lParam); - return 0; -} - -void initializeThreading() -{ - if (threadingWindowHandle) - return; - - WNDCLASSEX wcex; - memset(&wcex, 0, sizeof(WNDCLASSEX)); - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.lpfnWndProc = ThreadingWindowWndProc; - wcex.hInstance = Page::instanceHandle(); - wcex.lpszClassName = kThreadingWindowClassName; - RegisterClassEx(&wcex); - - threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, Page::instanceHandle(), 0); - threadingFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.MainThreadFired"); -} - -void callOnMainThread(MainThreadFunction* function, void* context) -{ - ASSERT(function); - ASSERT(threadingWindowHandle); - - if (processingCustomThreadingMessage) - LOG(Threading, "callOnMainThread() called recursively. Beware of nested PostMessage()s"); - - { - MutexLocker locker(functionQueueMutex()); - functionQueue().append(FunctionWithContext(function, context)); - } - - PostMessage(threadingWindowHandle, threadingFiredMessage, 0, 0); -} - -} // namespace WebCore diff --git a/WebCore/platform/win/WCDataObject.cpp b/WebCore/platform/win/WCDataObject.cpp index 940595d..5201bfa 100644 --- a/WebCore/platform/win/WCDataObject.cpp +++ b/WebCore/platform/win/WCDataObject.cpp @@ -23,7 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +#include "config.h" #include "WCDataObject.h" #include "PlatformString.h" diff --git a/WebCore/platform/win/WebCoreHistory.h b/WebCore/platform/win/WebCoreHistory.h deleted file mode 100644 index 9082b85..0000000 --- a/WebCore/platform/win/WebCoreHistory.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* Copyright (C) 2006, 2007 Apple Inc. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef WEBCORE_HISTORY_H_ -#define WEBCORE_HISTORY_H_ - -#include <unicode/umachine.h> - -namespace WebCore { - -class WebCoreHistoryProvider { -public: - virtual bool containsURL(const UChar* unicode, unsigned length) = 0; -}; - -class WebCoreHistory { -public: - static void setHistoryProvider(WebCoreHistoryProvider*); - static WebCoreHistoryProvider* historyProvider(); -}; - -} - -#endif diff --git a/WebCore/platform/win/WebCoreTextRenderer.cpp b/WebCore/platform/win/WebCoreTextRenderer.cpp index 2e48815..75ce003 100644 --- a/WebCore/platform/win/WebCoreTextRenderer.cpp +++ b/WebCore/platform/win/WebCoreTextRenderer.cpp @@ -33,6 +33,8 @@ namespace WebCore { +static bool shouldUseFontSmoothing = true; + static bool isOneLeftToRightRun(const TextRun& run) { for (int i = 0; i < run.length(); i++) { @@ -103,4 +105,24 @@ float WebCoreTextFloatWidth(const String& text, const Font& font) return StringTruncator::width(text, font, false); } +void WebCoreSetShouldUseFontSmoothing(bool smooth) +{ + shouldUseFontSmoothing = smooth; +} + +bool WebCoreShouldUseFontSmoothing() +{ + return shouldUseFontSmoothing; +} + +void WebCoreSetAlwaysUsesComplexTextCodePath(bool complex) +{ + Font::setCodePath(complex ? Font::Complex : Font::Auto); +} + +bool WebCoreAlwaysUsesComplexTextCodePath() +{ + return Font::codePath() == Font::Complex; +} + } // namespace WebCore diff --git a/WebCore/platform/win/WebCoreTextRenderer.h b/WebCore/platform/win/WebCoreTextRenderer.h index 59b82dc..7b72946 100644 --- a/WebCore/platform/win/WebCoreTextRenderer.h +++ b/WebCore/platform/win/WebCoreTextRenderer.h @@ -35,4 +35,10 @@ namespace WebCore { void WebCoreDrawDoubledTextAtPoint(GraphicsContext&, const String&, const IntPoint&, const Font&, const Color& topColor, const Color& bottomColor, int underlinedIndex = -1); float WebCoreTextFloatWidth(const String&, const Font&); + void WebCoreSetShouldUseFontSmoothing(bool); + bool WebCoreShouldUseFontSmoothing(); + + void WebCoreSetAlwaysUsesComplexTextCodePath(bool); + bool WebCoreAlwaysUsesComplexTextCodePath(); + } // namespace WebCore diff --git a/WebCore/platform/win/WheelEventWin.cpp b/WebCore/platform/win/WheelEventWin.cpp index 4a6132a..d272ba7 100644 --- a/WebCore/platform/win/WheelEventWin.cpp +++ b/WebCore/platform/win/WheelEventWin.cpp @@ -31,6 +31,7 @@ namespace WebCore { #define HIGH_BIT_MASK_SHORT 0x8000 +#define SPI_GETWHEELSCROLLCHARS 0x006C static IntPoint positionForEvent(HWND hWnd, LPARAM lParam) { @@ -45,6 +46,22 @@ static IntPoint globalPositionForEvent(HWND hWnd, LPARAM lParam) return point; } +int PlatformWheelEvent::horizontalLineMultiplier() const +{ + static ULONG scrollChars; + if (!scrollChars && !SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0)) + scrollChars = cLineMultiplier; + return scrollChars; +} + +int PlatformWheelEvent::verticalLineMultiplier() const +{ + static ULONG scrollLines; + if (!scrollLines && !SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0)) + scrollLines = cLineMultiplier; + return scrollLines; +} + PlatformWheelEvent::PlatformWheelEvent(HWND hWnd, WPARAM wParam, LPARAM lParam, bool isHorizontal) : m_position(positionForEvent(hWnd, lParam)) , m_globalPosition(globalPositionForEvent(hWnd, lParam)) @@ -53,18 +70,24 @@ PlatformWheelEvent::PlatformWheelEvent(HWND hWnd, WPARAM wParam, LPARAM lParam, , m_ctrlKey(wParam & MK_CONTROL) , m_altKey(GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT) , m_metaKey(m_altKey) // FIXME: We'll have to test other browsers - , m_isContinuous(false) { - float delta = short(HIWORD(wParam)) / (float)WHEEL_DELTA; + static ULONG scrollLines, scrollChars; + float delta = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; if (isHorizontal) { // Windows sends a positive delta for scrolling right, while AppKit // sends a negative delta. EventHandler expects the AppKit values, // so we have to negate our horizontal delta to match. - m_deltaX = -delta; + m_deltaX = -delta * horizontalLineMultiplier(); m_deltaY = 0; + m_granularity = ScrollByLineWheelEvent; } else { m_deltaX = 0; m_deltaY = delta; + int verticalMultiplier = verticalLineMultiplier(); + // A multiplier of -1 is used to mean that vertical wheel scrolling should be done by page. + m_granularity = (verticalMultiplier == -1) ? ScrollByPageWheelEvent : ScrollByLineWheelEvent; + if (m_granularity == ScrollByLineWheelEvent) + m_deltaY *= verticalMultiplier; } } diff --git a/WebCore/platform/win/WidgetWin.cpp b/WebCore/platform/win/WidgetWin.cpp index fc0adba..93dbf42 100644 --- a/WebCore/platform/win/WidgetWin.cpp +++ b/WebCore/platform/win/WidgetWin.cpp @@ -33,89 +33,19 @@ #include "FrameWin.h" #include "IntRect.h" #include "FrameView.h" -#include "WidgetClient.h" #include <winsock2.h> #include <windows.h> namespace WebCore { -class WidgetPrivate +Widget::Widget(PlatformWidget widget) { -public: - WidgetClient* client; - ScrollView* parent; - HWND containingWindow; - IntRect frameRect; - bool enabled; - Widget* capturingChild; - bool suppressInvalidation; -}; - -Widget::Widget() - : data(new WidgetPrivate) -{ - data->client = 0; - data->parent = 0; - data->containingWindow = 0; - data->enabled = true; - data->capturingChild = 0; - data->suppressInvalidation = false; + init(widget); } Widget::~Widget() { ASSERT(!parent()); - delete data; -} - -void Widget::setContainingWindow(HWND containingWindow) -{ - data->containingWindow = containingWindow; -} - -HWND Widget::containingWindow() const -{ - return data->containingWindow; -} - -void Widget::setClient(WidgetClient* c) -{ - data->client = c; -} - -WidgetClient* Widget::client() const -{ - return data->client; -} - -IntRect Widget::frameGeometry() const -{ - return data->frameRect; -} - -void Widget::setFrameGeometry(const IntRect &rect) -{ - data->frameRect = rect; -} - -void Widget::setParent(ScrollView* v) -{ - if (!v || !v->isAttachedToWindow()) - detachFromWindow(); - data->parent = v; - if (v && v->isAttachedToWindow()) - attachToWindow(); -} - -ScrollView* Widget::parent() const -{ - return data->parent; -} - -void Widget::removeFromParent() -{ - if (parent()) - parent()->removeChild(this); } void Widget::show() @@ -144,112 +74,26 @@ void Widget::setCursor(const Cursor& cursor) } } -IntPoint Widget::convertToContainingWindow(const IntPoint& point) const -{ - IntPoint windowPoint = point; - for (const Widget *parentWidget = parent(), *childWidget = this; - parentWidget; - childWidget = parentWidget, parentWidget = parentWidget->parent()) - windowPoint = parentWidget->convertChildToSelf(childWidget, windowPoint); - return windowPoint; -} - -IntPoint Widget::convertFromContainingWindow(const IntPoint& point) const -{ - IntPoint widgetPoint = point; - for (const Widget *parentWidget = parent(), *childWidget = this; - parentWidget; - childWidget = parentWidget, parentWidget = parentWidget->parent()) - widgetPoint = parentWidget->convertSelfToChild(childWidget, widgetPoint); - return widgetPoint; -} - -IntRect Widget::convertToContainingWindow(const IntRect& rect) const -{ - IntRect convertedRect = rect; - convertedRect.setLocation(convertToContainingWindow(convertedRect.location())); - return convertedRect; -} - -IntPoint Widget::convertChildToSelf(const Widget* child, const IntPoint& point) const -{ - return IntPoint(point.x() + child->x(), point.y() + child->y()); -} - -IntPoint Widget::convertSelfToChild(const Widget* child, const IntPoint& point) const -{ - return IntPoint(point.x() - child->x(), point.y() - child->y()); -} - void Widget::paint(GraphicsContext*, const IntRect&) { } -bool Widget::isEnabled() const -{ - return data->enabled; -} - -void Widget::setEnabled(bool e) -{ - if (e != data->enabled) { - data->enabled = e; - invalidate(); - } -} - -bool Widget::suppressInvalidation() const -{ - return data->suppressInvalidation; -} - -void Widget::setSuppressInvalidation(bool suppress) +void Widget::setFocus() { - data->suppressInvalidation = suppress; } -void Widget::invalidate() +void Widget::setIsSelected(bool) { - invalidateRect(IntRect(0, 0, width(), height())); } -void Widget::invalidateRect(const IntRect& r) -{ - if (data->suppressInvalidation) - return; - - if (!parent()) { - RECT rect = r; - ::InvalidateRect(containingWindow(), &rect, false); - if (isFrameView()) - static_cast<FrameView*>(this)->addToDirtyRegion(r); - return; - } - - // Get the root widget. - ScrollView* outermostView = parent(); - while (outermostView && outermostView->parent()) - outermostView = outermostView->parent(); - if (!outermostView) - return; - - IntRect windowRect = convertToContainingWindow(r); - - // Get our clip rect and intersect with it to ensure we don't invalidate too much. - IntRect clipRect = windowClipRect(); - windowRect.intersect(clipRect); - - RECT rect = windowRect; - ::InvalidateRect(containingWindow(), &rect, false); - outermostView->addToDirtyRegion(windowRect); -} - -void Widget::setFocus() +IntRect Widget::frameRect() const { + return m_frame; } -void Widget::setIsSelected(bool) +void Widget::setFrameRect(const IntRect& rect) { + m_frame = rect; } } // namespace WebCore diff --git a/WebCore/platform/win/WindowMessageBroadcaster.cpp b/WebCore/platform/win/WindowMessageBroadcaster.cpp index 2c2ef79..7088995 100644 --- a/WebCore/platform/win/WindowMessageBroadcaster.cpp +++ b/WebCore/platform/win/WindowMessageBroadcaster.cpp @@ -74,10 +74,10 @@ WindowMessageBroadcaster::~WindowMessageBroadcaster() void WindowMessageBroadcaster::addListener(WindowMessageListener* listener) { - if (!m_originalWndProc) { + if (m_listeners.isEmpty()) { + ASSERT(!m_originalWndProc); #pragma warning(disable: 4244 4312) m_originalWndProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(m_subclassedWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SubclassedWndProc))); - ASSERT(m_originalWndProc); } m_listeners.add(listener); @@ -105,8 +105,6 @@ void WindowMessageBroadcaster::destroy() void WindowMessageBroadcaster::unsubclassWindow() { - ASSERT(m_originalWndProc); - SetWindowLongPtr(m_subclassedWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_originalWndProc)); m_originalWndProc = 0; } |