diff options
Diffstat (limited to 'Source/WebCore/platform/mac')
65 files changed, 8263 insertions, 0 deletions
diff --git a/Source/WebCore/platform/mac/AutodrainedPool.mm b/Source/WebCore/platform/mac/AutodrainedPool.mm new file mode 100644 index 0000000..6febaef --- /dev/null +++ b/Source/WebCore/platform/mac/AutodrainedPool.mm @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#import "config.h" +#import "AutodrainedPool.h" + +namespace WebCore { + +AutodrainedPool::AutodrainedPool(int iterationLimit) + : m_iterationLimit(iterationLimit) + , m_iterationCount(0) + , m_pool([[NSAutoreleasePool alloc] init]) +{ +} + +AutodrainedPool::~AutodrainedPool() +{ + [m_pool drain]; +} + +void AutodrainedPool::cycle() +{ + if (++m_iterationCount == m_iterationLimit) { + [m_pool drain]; + m_pool = [[NSAutoreleasePool alloc] init]; + m_iterationCount = 0; + } +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/BlockExceptions.h b/Source/WebCore/platform/mac/BlockExceptions.h new file mode 100644 index 0000000..a3016d2 --- /dev/null +++ b/Source/WebCore/platform/mac/BlockExceptions.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2003 Apple Computer, 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. + */ + +#import <Foundation/NSException.h> + +void ReportBlockedObjCException(NSException *); + +#define BEGIN_BLOCK_OBJC_EXCEPTIONS @try { +#define END_BLOCK_OBJC_EXCEPTIONS } @catch(NSException *localException) { ReportBlockedObjCException(localException); } + diff --git a/Source/WebCore/platform/mac/BlockExceptions.mm b/Source/WebCore/platform/mac/BlockExceptions.mm new file mode 100644 index 0000000..f2dc1ec --- /dev/null +++ b/Source/WebCore/platform/mac/BlockExceptions.mm @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2003, 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. + */ + +#import "config.h" +#import "BlockExceptions.h" + +#import <wtf/Assertions.h> + +void ReportBlockedObjCException(NSException *exception) +{ +#if ASSERT_DISABLED + NSLog(@"*** WebKit discarding exception: <%@> %@", [exception name], [exception reason]); +#else + ASSERT_WITH_MESSAGE(0, "Uncaught exception - %@", exception); +#endif +} diff --git a/Source/WebCore/platform/mac/ClipboardMac.h b/Source/WebCore/platform/mac/ClipboardMac.h new file mode 100644 index 0000000..7187ecf --- /dev/null +++ b/Source/WebCore/platform/mac/ClipboardMac.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2004, 2006, 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. + */ + +#ifndef ClipboardMac_h +#define ClipboardMac_h + +#include "CachedResourceClient.h" +#include "Clipboard.h" +#include <wtf/RetainPtr.h> + +#ifdef __OBJC__ +@class NSImage; +@class NSPasteboard; +#else +class NSImage; +class NSPasteboard; +#endif + +namespace WebCore { + +class Frame; +class FileList; + +class ClipboardMac : public Clipboard, public CachedResourceClient { +public: + static PassRefPtr<ClipboardMac> create(ClipboardType clipboardType, NSPasteboard *pasteboard, ClipboardAccessPolicy policy, Frame* frame) + { + return adoptRef(new ClipboardMac(clipboardType, pasteboard, policy, frame)); + } + + virtual ~ClipboardMac(); + + void clearData(const String& type); + void clearAllData(); + String getData(const String& type, bool& success) const; + bool setData(const String& type, const String& data); + + virtual bool hasData(); + + // extensions beyond IE's API + virtual HashSet<String> types() const; + virtual PassRefPtr<FileList> files() const; + + void setDragImage(CachedImage*, const IntPoint&); + void setDragImageElement(Node *, const IntPoint&); + + virtual DragImageRef createDragImage(IntPoint& dragLoc) const; +#if ENABLE(DRAG_SUPPORT) + virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*); +#endif + virtual void writeRange(Range*, Frame* frame); + virtual void writeURL(const KURL&, const String&, Frame* frame); + virtual void writePlainText(const String&); + + // Methods for getting info in Cocoa's type system + NSImage *dragNSImage(NSPoint&) const; // loc converted from dragLoc, based on whole image size + NSPasteboard *pasteboard() { return m_pasteboard.get(); } + +private: + ClipboardMac(ClipboardType, NSPasteboard *, ClipboardAccessPolicy, Frame*); + + void setDragImage(CachedImage*, Node*, const IntPoint&); + + RetainPtr<NSPasteboard> m_pasteboard; + int m_changeCount; + Frame* m_frame; // used on the source side to generate dragging images +}; + +} + +#endif diff --git a/Source/WebCore/platform/mac/ClipboardMac.mm b/Source/WebCore/platform/mac/ClipboardMac.mm new file mode 100644 index 0000000..10d196a --- /dev/null +++ b/Source/WebCore/platform/mac/ClipboardMac.mm @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "ClipboardMac.h" + +#import "DOMElementInternal.h" +#import "DragClient.h" +#import "DragController.h" +#import "DragData.h" +#import "Editor.h" +#import "FileList.h" +#import "Frame.h" +#import "Image.h" +#import "Page.h" +#import "Pasteboard.h" +#import "RenderImage.h" +#import "ScriptExecutionContext.h" +#import "SecurityOrigin.h" +#import "WebCoreSystemInterface.h" + +#ifdef BUILDING_ON_TIGER +typedef unsigned NSUInteger; +#endif + +namespace WebCore { + +PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame) +{ + return ClipboardMac::create(DragAndDrop, [dragData->platformData() draggingPasteboard], policy, frame); +} + +ClipboardMac::ClipboardMac(ClipboardType clipboardType, NSPasteboard *pasteboard, ClipboardAccessPolicy policy, Frame *frame) + : Clipboard(policy, clipboardType) + , m_pasteboard(pasteboard) + , m_frame(frame) +{ + m_changeCount = [m_pasteboard.get() changeCount]; +} + +ClipboardMac::~ClipboardMac() +{ +} + +bool ClipboardMac::hasData() +{ + return m_pasteboard && [m_pasteboard.get() types] && [[m_pasteboard.get() types] count] > 0; +} + +static RetainPtr<NSString> cocoaTypeFromHTMLClipboardType(const String& type) +{ + String qType = type.stripWhiteSpace(); + + // two special cases for IE compatibility + if (qType == "Text") + return NSStringPboardType; + if (qType == "URL") + return NSURLPboardType; + + // Ignore any trailing charset - JS strings are Unicode, which encapsulates the charset issue + if (qType == "text/plain" || qType.startsWith("text/plain;")) + return NSStringPboardType; + if (qType == "text/uri-list") + // special case because UTI doesn't work with Cocoa's URL type + return NSURLPboardType; // note special case in getData to read NSFilenamesType + + // Try UTI now + NSString *mimeType = qType; + RetainPtr<CFStringRef> utiType(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (CFStringRef)mimeType, NULL)); + if (utiType) { + CFStringRef pbType = UTTypeCopyPreferredTagWithClass(utiType.get(), kUTTagClassNSPboardType); + if (pbType) + return (NSString *)pbType; + } + + // No mapping, just pass the whole string though + return (NSString *)qType; +} + +static String utiTypeFromCocoaType(NSString *type) +{ + RetainPtr<CFStringRef> utiType(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassNSPboardType, (CFStringRef)type, NULL)); + if (utiType) { + RetainPtr<CFStringRef> mimeType(AdoptCF, UTTypeCopyPreferredTagWithClass(utiType.get(), kUTTagClassMIMEType)); + if (mimeType) + return String(mimeType.get()); + } + return String(); +} + +static void addHTMLClipboardTypesForCocoaType(HashSet<String>& resultTypes, NSString *cocoaType, NSPasteboard *pasteboard) +{ + // UTI may not do these right, so make sure we get the right, predictable result + if ([cocoaType isEqualToString:NSStringPboardType]) { + resultTypes.add("text/plain"); + return; + } + if ([cocoaType isEqualToString:NSURLPboardType]) { + resultTypes.add("text/uri-list"); + return; + } + if ([cocoaType isEqualToString:NSFilenamesPboardType]) { + // If file list is empty, add nothing. + // Note that there is a chance that the file list count could have changed since we grabbed the types array. + // However, this is not really an issue for us doing a sanity check here. + NSArray *fileList = [pasteboard propertyListForType:NSFilenamesPboardType]; + if ([fileList count]) { + // It is unknown if NSFilenamesPboardType always implies NSURLPboardType in Cocoa, + // but NSFilenamesPboardType should imply both 'text/uri-list' and 'Files' + resultTypes.add("text/uri-list"); + resultTypes.add("Files"); + } + return; + } + String utiType = utiTypeFromCocoaType(cocoaType); + if (!utiType.isEmpty()) { + resultTypes.add(utiType); + return; + } + // No mapping, just pass the whole string though + resultTypes.add(cocoaType); +} + +void ClipboardMac::clearData(const String& type) +{ + if (policy() != ClipboardWritable) + return; + + // note NSPasteboard enforces changeCount itself on writing - can't write if not the owner + + if (RetainPtr<NSString> cocoaType = cocoaTypeFromHTMLClipboardType(type)) + [m_pasteboard.get() setString:@"" forType:cocoaType.get()]; +} + +void ClipboardMac::clearAllData() +{ + if (policy() != ClipboardWritable) + return; + + // note NSPasteboard enforces changeCount itself on writing - can't write if not the owner + + [m_pasteboard.get() declareTypes:[NSArray array] owner:nil]; +} + +static NSArray *absoluteURLsFromPasteboardFilenames(NSPasteboard* pasteboard, bool onlyFirstURL = false) +{ + NSArray *fileList = [pasteboard propertyListForType:NSFilenamesPboardType]; + + // FIXME: Why does this code need to guard against bad values on the pasteboard? + ASSERT(!fileList || [fileList isKindOfClass:[NSArray class]]); + if (!fileList || ![fileList isKindOfClass:[NSArray class]] || ![fileList count]) + return nil; + + NSUInteger count = onlyFirstURL ? 1 : [fileList count]; + NSMutableArray *urls = [NSMutableArray array]; + for (NSUInteger i = 0; i < count; i++) { + NSString *string = [fileList objectAtIndex:i]; + + ASSERT([string isKindOfClass:[NSString class]]); // Added to understand why this if code is here + if (![string isKindOfClass:[NSString class]]) + return nil; // Non-string object in the list, bail out! FIXME: When can this happen? + + NSURL *url = [NSURL fileURLWithPath:string]; + [urls addObject:[url absoluteString]]; + } + return urls; +} + +static NSArray *absoluteURLsFromPasteboard(NSPasteboard* pasteboard, bool onlyFirstURL = false) +{ + // NOTE: We must always check [availableTypes containsObject:] before accessing pasteboard data + // or CoreFoundation will printf when there is not data of the corresponding type. + NSArray *availableTypes = [pasteboard types]; + + // Try NSFilenamesPboardType because it contains a list + if ([availableTypes containsObject:NSFilenamesPboardType]) { + if (NSArray* absoluteURLs = absoluteURLsFromPasteboardFilenames(pasteboard, onlyFirstURL)) + return absoluteURLs; + } + + // Fallback to NSURLPboardType (which is a single URL) + if ([availableTypes containsObject:NSURLPboardType]) { + if (NSURL *url = [NSURL URLFromPasteboard:pasteboard]) + return [NSArray arrayWithObject:[url absoluteString]]; + } + + // No file paths on the pasteboard, return nil + return nil; +} + +String ClipboardMac::getData(const String& type, bool& success) const +{ + success = false; + if (policy() != ClipboardReadable) + return String(); + + RetainPtr<NSString> cocoaType = cocoaTypeFromHTMLClipboardType(type); + NSString *cocoaValue = nil; + + // Grab the value off the pasteboard corresponding to the cocoaType + if ([cocoaType.get() isEqualToString:NSURLPboardType]) { + // "URL" and "text/url-list" both map to NSURLPboardType in cocoaTypeFromHTMLClipboardType(), "URL" only wants the first URL + bool onlyFirstURL = (type == "URL"); + NSArray *absoluteURLs = absoluteURLsFromPasteboard(m_pasteboard.get(), onlyFirstURL); + cocoaValue = [absoluteURLs componentsJoinedByString:@"\n"]; + } else if ([cocoaType.get() isEqualToString:NSStringPboardType]) { + cocoaValue = [[m_pasteboard.get() stringForType:cocoaType.get()] precomposedStringWithCanonicalMapping]; + } else if (cocoaType) + cocoaValue = [m_pasteboard.get() stringForType:cocoaType.get()]; + + // Enforce changeCount ourselves for security. We check after reading instead of before to be + // sure it doesn't change between our testing the change count and accessing the data. + if (cocoaValue && m_changeCount == [m_pasteboard.get() changeCount]) { + success = true; + return cocoaValue; + } + + return String(); +} + +bool ClipboardMac::setData(const String &type, const String &data) +{ + if (policy() != ClipboardWritable) + return false; + // note NSPasteboard enforces changeCount itself on writing - can't write if not the owner + + RetainPtr<NSString> cocoaType = cocoaTypeFromHTMLClipboardType(type); + NSString *cocoaData = data; + + if ([cocoaType.get() isEqualToString:NSURLPboardType]) { + [m_pasteboard.get() addTypes:[NSArray arrayWithObject:NSURLPboardType] owner:nil]; + NSURL *url = [[NSURL alloc] initWithString:cocoaData]; + [url writeToPasteboard:m_pasteboard.get()]; + + if ([url isFileURL] && m_frame->document()->securityOrigin()->canLoadLocalResources()) { + [m_pasteboard.get() addTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil]; + NSArray *fileList = [NSArray arrayWithObject:[url path]]; + [m_pasteboard.get() setPropertyList:fileList forType:NSFilenamesPboardType]; + } + + [url release]; + return true; + } + + if (cocoaType) { + // everything else we know of goes on the pboard as a string + [m_pasteboard.get() addTypes:[NSArray arrayWithObject:cocoaType.get()] owner:nil]; + return [m_pasteboard.get() setString:cocoaData forType:cocoaType.get()]; + } + + return false; +} + +HashSet<String> ClipboardMac::types() const +{ + if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable) + return HashSet<String>(); + + NSArray *types = [m_pasteboard.get() types]; + + // Enforce changeCount ourselves for security. We check after reading instead of before to be + // sure it doesn't change between our testing the change count and accessing the data. + if (m_changeCount != [m_pasteboard.get() changeCount]) + return HashSet<String>(); + + HashSet<String> result; + NSUInteger count = [types count]; + // FIXME: This loop could be split into two stages. One which adds all the HTML5 specified types + // and a second which adds all the extra types from the cocoa clipboard (which is Mac-only behavior). + for (NSUInteger i = 0; i < count; i++) { + NSString *pbType = [types objectAtIndex:i]; + if ([pbType isEqualToString:@"NeXT plain ascii pasteboard type"]) + continue; // skip this ancient type that gets auto-supplied by some system conversion + + addHTMLClipboardTypesForCocoaType(result, pbType, m_pasteboard.get()); + } + + return result; +} + +// FIXME: We could cache the computed fileList if necessary +// Currently each access gets a new copy, setData() modifications to the +// clipboard are not reflected in any FileList objects the page has accessed and stored +PassRefPtr<FileList> ClipboardMac::files() const +{ + if (policy() != ClipboardReadable) + return FileList::create(); + + NSArray *absoluteURLs = absoluteURLsFromPasteboardFilenames(m_pasteboard.get()); + NSUInteger count = [absoluteURLs count]; + + RefPtr<FileList> fileList = FileList::create(); + for (NSUInteger x = 0; x < count; x++) { + NSURL *absoluteURL = [NSURL URLWithString:[absoluteURLs objectAtIndex:x]]; + ASSERT([absoluteURL isFileURL]); + fileList->append(File::create([absoluteURL path])); + } + return fileList.release(); // We will always return a FileList, sometimes empty +} + +// The rest of these getters don't really have any impact on security, so for now make no checks + +void ClipboardMac::setDragImage(CachedImage* img, const IntPoint &loc) +{ + setDragImage(img, 0, loc); +} + +void ClipboardMac::setDragImageElement(Node *node, const IntPoint &loc) +{ + setDragImage(0, node, loc); +} + +void ClipboardMac::setDragImage(CachedImage* image, Node *node, const IntPoint &loc) +{ + if (policy() == ClipboardImageWritable || policy() == ClipboardWritable) { + if (m_dragImage) + m_dragImage->removeClient(this); + m_dragImage = image; + if (m_dragImage) + m_dragImage->addClient(this); + + m_dragLoc = loc; + m_dragImageElement = node; + + if (dragStarted() && m_changeCount == [m_pasteboard.get() changeCount]) { + NSPoint cocoaLoc; + NSImage* cocoaImage = dragNSImage(cocoaLoc); + if (cocoaImage) { + // Dashboard wants to be able to set the drag image during dragging, but Cocoa does not allow this. + // Instead we must drop down to the CoreGraphics API. + wkSetDragImage(cocoaImage, cocoaLoc); + + // Hack: We must post an event to wake up the NSDragManager, which is sitting in a nextEvent call + // up the stack from us because the CoreFoundation drag manager does not use the run loop by itself. + // This is the most innocuous event to use, per Kristen Forster. + NSEvent* ev = [NSEvent mouseEventWithType:NSMouseMoved location:NSZeroPoint + modifierFlags:0 timestamp:0 windowNumber:0 context:nil eventNumber:0 clickCount:0 pressure:0]; + [NSApp postEvent:ev atStart:YES]; + } + } + // Else either 1) we haven't started dragging yet, so we rely on the part to install this drag image + // as part of getting the drag kicked off, or 2) Someone kept a ref to the clipboard and is trying to + // set the image way too late. + } +} + +void ClipboardMac::writeRange(Range* range, Frame* frame) +{ + ASSERT(range); + ASSERT(frame); + Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selection()->granularity() == WordGranularity, frame); +} + +void ClipboardMac::writePlainText(const String& text) +{ + Pasteboard::writePlainText(m_pasteboard.get(), text); +} + +void ClipboardMac::writeURL(const KURL& url, const String& title, Frame* frame) +{ + ASSERT(frame); + ASSERT(m_pasteboard); + Pasteboard::writeURL(m_pasteboard.get(), nil, url, title, frame); +} + +#if ENABLE(DRAG_SUPPORT) +void ClipboardMac::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame) +{ + ASSERT(frame); + if (Page* page = frame->page()) + page->dragController()->client()->declareAndWriteDragImage(m_pasteboard.get(), kit(element), url, title, frame); +} +#endif // ENABLE(DRAG_SUPPORT) + +DragImageRef ClipboardMac::createDragImage(IntPoint& loc) const +{ + NSPoint nsloc = {loc.x(), loc.y()}; + DragImageRef result = dragNSImage(nsloc); + loc = (IntPoint)nsloc; + return result; +} + +NSImage *ClipboardMac::dragNSImage(NSPoint& loc) const +{ + NSImage *result = nil; + if (m_dragImageElement) { + if (m_frame) { + NSRect imageRect; + NSRect elementRect; + result = m_frame->snapshotDragImage(m_dragImageElement.get(), &imageRect, &elementRect); + // Client specifies point relative to element, not the whole image, which may include child + // layers spread out all over the place. + loc.x = elementRect.origin.x - imageRect.origin.x + m_dragLoc.x(); + loc.y = elementRect.origin.y - imageRect.origin.y + m_dragLoc.y(); + loc.y = imageRect.size.height - loc.y; + } + } else if (m_dragImage) { + result = m_dragImage->image()->getNSImage(); + + loc = m_dragLoc; + loc.y = [result size].height - loc.y; + } + return result; +} + +} diff --git a/Source/WebCore/platform/mac/ContextMenuItemMac.mm b/Source/WebCore/platform/mac/ContextMenuItemMac.mm new file mode 100644 index 0000000..2d72ba9 --- /dev/null +++ b/Source/WebCore/platform/mac/ContextMenuItemMac.mm @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2006 Apple Computer, 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 "ContextMenuItem.h" + +#if ENABLE(CONTEXT_MENUS) + +#include "ContextMenu.h" + +namespace WebCore { + +static NSMutableArray* menuToArray(NSMenu* menu) +{ + NSMutableArray* itemsArray = [NSMutableArray array]; + int total = [menu numberOfItems]; + for (int i = 0; i < total; i++) + [itemsArray addObject:[menu itemAtIndex:i]]; + + return itemsArray; +} + +ContextMenuItem::ContextMenuItem(NSMenuItem* item) +{ + m_platformDescription = item; +} + +ContextMenuItem::ContextMenuItem(ContextMenu* subMenu) +{ + NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + m_platformDescription = item; + [item release]; + + [m_platformDescription.get() setTag:ContextMenuItemTagNoAction]; + if (subMenu) + setSubMenu(subMenu); +} + +static PlatformMenuItemDescription createPlatformMenuItemDescription(ContextMenuItemType type, ContextMenuAction action, const String& title, bool enabled, bool checked) +{ + if (type == SeparatorType) + return [[NSMenuItem separatorItem] retain]; + + NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""]; + [item setEnabled:enabled]; + [item setState:checked ? NSOnState : NSOffState]; + [item setTag:action]; + + return item; +} + +ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu) +{ + m_platformDescription.adoptNS(createPlatformMenuItemDescription(type, action, title, true, false)); + + if (subMenu) + setSubMenu(subMenu); +} + +ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, bool enabled, bool checked) +{ + m_platformDescription.adoptNS(createPlatformMenuItemDescription(type, action, title, enabled, checked)); +} + +ContextMenuItem::ContextMenuItem(ContextMenuAction action, const String& title, bool enabled, bool checked, Vector<ContextMenuItem>& subMenuItems) +{ + m_platformDescription.adoptNS(createPlatformMenuItemDescription(SubmenuType, action, title, enabled, checked)); + + setSubMenu(subMenuItems); +} + +ContextMenuItem::~ContextMenuItem() +{ +} + +NSMenuItem* ContextMenuItem::releasePlatformDescription() +{ + NSMenuItem* item = [m_platformDescription.get() retain]; + m_platformDescription = 0; + return item; +} + +ContextMenuItemType ContextMenuItem::type() const +{ + if ([m_platformDescription.get() isSeparatorItem]) + return SeparatorType; + if ([m_platformDescription.get() hasSubmenu]) + return SubmenuType; + return ActionType; +} + +ContextMenuAction ContextMenuItem::action() const +{ + return static_cast<ContextMenuAction>([m_platformDescription.get() tag]); +} + +String ContextMenuItem::title() const +{ + return [m_platformDescription.get() title]; +} + +NSMutableArray* ContextMenuItem::platformSubMenu() const +{ + return menuToArray([m_platformDescription.get() submenu]); +} + +void ContextMenuItem::setType(ContextMenuItemType type) +{ + if (type == SeparatorType) + m_platformDescription = [NSMenuItem separatorItem]; +} + +void ContextMenuItem::setAction(ContextMenuAction action) +{ + [m_platformDescription.get() setTag:action]; +} + +void ContextMenuItem::setTitle(const String& title) +{ + [m_platformDescription.get() setTitle:title]; +} + +void ContextMenuItem::setSubMenu(ContextMenu* menu) +{ + NSArray* subMenuArray = menu->platformDescription(); + NSMenu* subMenu = [[NSMenu alloc] init]; + [subMenu setAutoenablesItems:NO]; + for (unsigned i = 0; i < [subMenuArray count]; i++) + [subMenu insertItem:[subMenuArray objectAtIndex:i] atIndex:i]; + [m_platformDescription.get() setSubmenu:subMenu]; + [subMenu release]; +} + +void ContextMenuItem::setSubMenu(Vector<ContextMenuItem>& subMenuItems) +{ + NSMenu* subMenu = [[NSMenu alloc] init]; + [subMenu setAutoenablesItems:NO]; + for (unsigned i = 0; i < subMenuItems.size(); ++i) + [subMenu addItem:subMenuItems[i].releasePlatformDescription()]; + + [m_platformDescription.get() setSubmenu:subMenu]; + [subMenu release]; +} + +void ContextMenuItem::setChecked(bool checked) +{ + if (checked) + [m_platformDescription.get() setState:NSOnState]; + else + [m_platformDescription.get() setState:NSOffState]; +} + +void ContextMenuItem::setEnabled(bool enable) +{ + [m_platformDescription.get() setEnabled:enable]; +} + +bool ContextMenuItem::enabled() const +{ + return [m_platformDescription.get() isEnabled]; +} + +bool ContextMenuItem::checked() const +{ + return [m_platformDescription.get() state] == NSOnState; +} + +} // namespace WebCore + +#endif // ENABLE(CONTEXT_MENUS) diff --git a/Source/WebCore/platform/mac/ContextMenuMac.mm b/Source/WebCore/platform/mac/ContextMenuMac.mm new file mode 100644 index 0000000..c9451b9 --- /dev/null +++ b/Source/WebCore/platform/mac/ContextMenuMac.mm @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2006 Apple Computer, 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 "ContextMenu.h" + +#if ENABLE(CONTEXT_MENUS) + +namespace WebCore { + +ContextMenu::ContextMenu() +{ + NSMutableArray* array = [[NSMutableArray alloc] init]; + m_platformDescription = array; + [array release]; +} + +ContextMenu::ContextMenu(const PlatformMenuDescription menu) + : m_platformDescription(menu) +{ +} + +ContextMenu::~ContextMenu() +{ +} + +void ContextMenu::appendItem(ContextMenuItem& item) +{ + NSMenuItem* platformItem = item.releasePlatformDescription(); + + [m_platformDescription.get() addObject:platformItem]; + [platformItem release]; +} + +void ContextMenu::insertItem(unsigned position, ContextMenuItem& item) +{ + NSMenuItem* platformItem = item.releasePlatformDescription(); + + [m_platformDescription.get() insertObject:platformItem atIndex:position]; + [platformItem release]; +} + +unsigned ContextMenu::itemCount() const +{ + return [m_platformDescription.get() count]; +} + +void ContextMenu::setPlatformDescription(NSMutableArray* menu) +{ + if (m_platformDescription.get() != menu) + m_platformDescription = menu; +} + +NSMutableArray* ContextMenu::platformDescription() const +{ + return m_platformDescription.get(); +} + +NSMutableArray* ContextMenu::releasePlatformDescription() +{ + return m_platformDescription.releaseRef(); +} + +Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription menu) +{ + Vector<ContextMenuItem> items; + unsigned count = [menu count]; + if (menu) + items.reserveCapacity(count); + + for (unsigned i = 0; i < count; ++i) + items.append(ContextMenuItem([menu objectAtIndex:i])); + + return items; +} + +PlatformMenuDescription platformMenuDescription(Vector<ContextMenuItem>& menuItemVector) +{ + PlatformMenuDescription platformMenu = [[NSMutableArray alloc] initWithCapacity:menuItemVector.size()]; + for (unsigned i = 0; i < menuItemVector.size(); ++i) { + PlatformMenuItemDescription platformItem = menuItemVector[i].releasePlatformDescription(); + [platformMenu addObject:platformItem]; + [platformItem release]; + } + + return [platformMenu autorelease]; +} + +} // namespace WebCore + +#endif // ENABLE(CONTEXT_MENUS) diff --git a/Source/WebCore/platform/mac/CookieJar.mm b/Source/WebCore/platform/mac/CookieJar.mm new file mode 100644 index 0000000..df24b03 --- /dev/null +++ b/Source/WebCore/platform/mac/CookieJar.mm @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2003, 2006, 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. + */ + +#import "config.h" +#import "CookieJar.h" + +#import "BlockExceptions.h" +#import "Cookie.h" +#import "Document.h" +#import "KURL.h" +#import <wtf/RetainPtr.h> + +#ifdef BUILDING_ON_TIGER +typedef unsigned NSUInteger; +#endif + +@interface NSHTTPCookie (WebCoreHTTPOnlyCookies) +- (BOOL)isHTTPOnly; +@end + +namespace WebCore { + +static bool isHTTPOnly(NSHTTPCookie *cookie) +{ + // Once we require a newer version of Foundation with the isHTTPOnly method, + // we can eliminate the instancesRespondToSelector: check. + static bool supportsHTTPOnlyCookies = [NSHTTPCookie instancesRespondToSelector:@selector(isHTTPOnly)]; + return supportsHTTPOnlyCookies && [cookie isHTTPOnly]; +} + +static RetainPtr<NSArray> filterCookies(NSArray *unfilteredCookies) +{ + NSUInteger count = [unfilteredCookies count]; + RetainPtr<NSMutableArray> filteredCookies(AdoptNS, [[NSMutableArray alloc] initWithCapacity:count]); + + for (NSUInteger i = 0; i < count; ++i) { + NSHTTPCookie *cookie = (NSHTTPCookie *)[unfilteredCookies objectAtIndex:i]; + + // <rdar://problem/5632883> On 10.5, NSHTTPCookieStorage would store an empty cookie, + // which would be sent as "Cookie: =". We have a workaround in setCookies() to prevent + // that, but we also need to avoid sending cookies that were previously stored, and + // there's no harm to doing this check because such a cookie is never valid. + if (![[cookie name] length]) + continue; + + if (isHTTPOnly(cookie)) + continue; + + [filteredCookies.get() addObject:cookie]; + } + + return filteredCookies; +} + +String cookies(const Document*, const KURL& url) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSURL *cookieURL = url; + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + return [[NSHTTPCookie requestHeaderFieldsWithCookies:filterCookies(cookies).get()] objectForKey:@"Cookie"]; + + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String cookieRequestHeaderFieldValue(const Document*, const KURL& url) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSURL *cookieURL = url; + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + return [[NSHTTPCookie requestHeaderFieldsWithCookies:cookies] objectForKey:@"Cookie"]; + + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +void setCookies(Document* document, const KURL& url, const String& cookieStr) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + // <rdar://problem/5632883> On 10.5, NSHTTPCookieStorage would store an empty cookie, + // which would be sent as "Cookie: =". + if (cookieStr.isEmpty()) + return; + + // <http://bugs.webkit.org/show_bug.cgi?id=6531>, <rdar://4409034> + // cookiesWithResponseHeaderFields doesn't parse cookies without a value + String cookieString = cookieStr.contains('=') ? cookieStr : cookieStr + "="; + + NSURL *cookieURL = url; + NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary dictionaryWithObject:cookieString forKey:@"Set-Cookie"] forURL:cookieURL]; + [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:filterCookies(cookies).get() forURL:cookieURL mainDocumentURL:document->firstPartyForCookies()]; + + END_BLOCK_OBJC_EXCEPTIONS; +} + +bool cookiesEnabled(const Document*) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSHTTPCookieAcceptPolicy cookieAcceptPolicy = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookieAcceptPolicy]; + return cookieAcceptPolicy == NSHTTPCookieAcceptPolicyAlways || cookieAcceptPolicy == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; + + END_BLOCK_OBJC_EXCEPTIONS; + return false; +} + +bool getRawCookies(const Document*, const KURL& url, Vector<Cookie>& rawCookies) +{ + rawCookies.clear(); + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSURL *cookieURL = url; + NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + + NSUInteger count = [cookies count]; + rawCookies.reserveCapacity(count); + for (NSUInteger i = 0; i < count; ++i) { + NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i]; + NSString *name = [cookie name]; + NSString *value = [cookie value]; + NSString *domain = [cookie domain]; + NSString *path = [cookie path]; + NSTimeInterval expires = [[cookie expiresDate] timeIntervalSince1970] * 1000; + bool httpOnly = [cookie isHTTPOnly]; + bool secure = [cookie isSecure]; + bool session = [cookie isSessionOnly]; + rawCookies.uncheckedAppend(Cookie(name, value, domain, path, expires, httpOnly, secure, session)); + } + + END_BLOCK_OBJC_EXCEPTIONS; + return true; +} + +void deleteCookie(const Document*, const KURL& url, const String& cookieName) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSURL *cookieURL = url; + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSArray *cookies = [cookieStorage cookiesForURL:cookieURL]; + NSString *cookieNameString = (NSString *) cookieName; + + NSUInteger count = [cookies count]; + for (NSUInteger i = 0; i < count; ++i) { + NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i]; + if ([[cookie name] isEqualToString:cookieNameString]) { + [cookieStorage deleteCookie:cookie]; + break; + } + } + + END_BLOCK_OBJC_EXCEPTIONS; +} + +} diff --git a/Source/WebCore/platform/mac/CursorMac.mm b/Source/WebCore/platform/mac/CursorMac.mm new file mode 100644 index 0000000..c006cbc --- /dev/null +++ b/Source/WebCore/platform/mac/CursorMac.mm @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2004, 2006, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "Cursor.h" + +#import "BlockExceptions.h" +#import <wtf/StdLibExtras.h> + +@interface WebCoreCursorBundle : NSObject { } +@end + +@implementation WebCoreCursorBundle +@end + +namespace WebCore { + +// Simple NSCursor calls shouldn't need protection, +// but creating a cursor with a bad image might throw. + +static RetainPtr<NSCursor> createCustomCursor(Image* image, const IntPoint& hotSpot) +{ + // FIXME: The cursor won't animate. Not sure if that's a big deal. + NSImage* nsImage = image->getNSImage(); + if (!nsImage) + return 0; + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return RetainPtr<NSCursor>(AdoptNS, [[NSCursor alloc] initWithImage:nsImage hotSpot:hotSpot]); + END_BLOCK_OBJC_EXCEPTIONS; + return 0; +} + +// Leak these cursors intentionally, that way we won't waste time trying to clean them +// up at process exit time. +static NSCursor* leakNamedCursor(const char* name, int x, int y) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSString* resourceName = [[NSString alloc] initWithUTF8String:name]; + NSImage* cursorImage = [[NSImage alloc] initWithContentsOfFile: + [[NSBundle bundleForClass:[WebCoreCursorBundle class]] + pathForResource:resourceName ofType:@"png"]]; + [resourceName release]; + NSCursor* cursor = 0; + if (cursorImage) { + NSPoint hotSpotPoint = {x, y}; // workaround for 4213314 + cursor = [[NSCursor alloc] initWithImage:cursorImage hotSpot:hotSpotPoint]; + [cursorImage release]; + } + return cursor; + END_BLOCK_OBJC_EXCEPTIONS; + return nil; +} + +void Cursor::ensurePlatformCursor() const +{ + if (m_platformCursor) + return; + + switch (m_type) { + case Cursor::Pointer: + m_platformCursor = [NSCursor arrowCursor]; + break; + case Cursor::Cross: + m_platformCursor = leakNamedCursor("crossHairCursor", 11, 11); + break; + case Cursor::Hand: + m_platformCursor = leakNamedCursor("linkCursor", 6, 1); + break; + case Cursor::IBeam: + m_platformCursor = [NSCursor IBeamCursor]; + break; + case Cursor::Wait: + m_platformCursor = leakNamedCursor("waitCursor", 7, 7); + break; + case Cursor::Help: + m_platformCursor = leakNamedCursor("helpCursor", 8, 8); + break; + case Cursor::Move: + case Cursor::MiddlePanning: + m_platformCursor = leakNamedCursor("moveCursor", 7, 7); + break; + case Cursor::EastResize: + case Cursor::EastPanning: + m_platformCursor = leakNamedCursor("eastResizeCursor", 14, 7); + break; + case Cursor::NorthResize: + case Cursor::NorthPanning: + m_platformCursor = leakNamedCursor("northResizeCursor", 7, 1); + break; + case Cursor::NorthEastResize: + case Cursor::NorthEastPanning: + m_platformCursor = leakNamedCursor("northEastResizeCursor", 14, 1); + break; + case Cursor::NorthWestResize: + case Cursor::NorthWestPanning: + m_platformCursor = leakNamedCursor("northWestResizeCursor", 0, 0); + break; + case Cursor::SouthResize: + case Cursor::SouthPanning: + m_platformCursor = leakNamedCursor("southResizeCursor", 7, 14); + break; + case Cursor::SouthEastResize: + case Cursor::SouthEastPanning: + m_platformCursor = leakNamedCursor("southEastResizeCursor", 14, 14); + break; + case Cursor::SouthWestResize: + case Cursor::SouthWestPanning: + m_platformCursor = leakNamedCursor("southWestResizeCursor", 1, 14); + break; + case Cursor::WestResize: + m_platformCursor = leakNamedCursor("westResizeCursor", 1, 7); + break; + case Cursor::NorthSouthResize: + m_platformCursor = leakNamedCursor("northSouthResizeCursor", 7, 7); + break; + case Cursor::EastWestResize: + case Cursor::WestPanning: + m_platformCursor = leakNamedCursor("eastWestResizeCursor", 7, 7); + break; + case Cursor::NorthEastSouthWestResize: + m_platformCursor = leakNamedCursor("northEastSouthWestResizeCursor", 7, 7); + break; + case Cursor::NorthWestSouthEastResize: + m_platformCursor = leakNamedCursor("northWestSouthEastResizeCursor", 7, 7); + break; + case Cursor::ColumnResize: + m_platformCursor = [NSCursor resizeLeftRightCursor]; + break; + case Cursor::RowResize: + m_platformCursor = [NSCursor resizeUpDownCursor]; + break; + case Cursor::VerticalText: + m_platformCursor = leakNamedCursor("verticalTextCursor", 7, 7); + break; + case Cursor::Cell: + m_platformCursor = leakNamedCursor("cellCursor", 7, 7); + break; + case Cursor::ContextMenu: + m_platformCursor = leakNamedCursor("contextMenuCursor", 3, 2); + break; + case Cursor::Alias: + m_platformCursor = leakNamedCursor("aliasCursor", 11, 3); + break; + case Cursor::Progress: + m_platformCursor = leakNamedCursor("progressCursor", 3, 2); + break; + case Cursor::NoDrop: + m_platformCursor = leakNamedCursor("noDropCursor", 3, 1); + break; + case Cursor::Copy: + m_platformCursor = leakNamedCursor("copyCursor", 3, 2); + break; + case Cursor::None: + m_platformCursor = leakNamedCursor("noneCursor", 7, 7); + break; + case Cursor::NotAllowed: + m_platformCursor = leakNamedCursor("notAllowedCursor", 11, 11); + break; + case Cursor::ZoomIn: + m_platformCursor = leakNamedCursor("zoomInCursor", 7, 7); + break; + case Cursor::ZoomOut: + m_platformCursor = leakNamedCursor("zoomOutCursor", 7, 7); + break; + case Cursor::Grab: + m_platformCursor = [NSCursor openHandCursor]; + break; + case Cursor::Grabbing: + m_platformCursor = [NSCursor closedHandCursor]; + break; + case Cursor::Custom: + m_platformCursor = createCustomCursor(m_image.get(), m_hotSpot); + break; + } +} + +Cursor::Cursor(const Cursor& other) + : m_type(other.m_type) + , m_image(other.m_image) + , m_hotSpot(other.m_hotSpot) + , m_platformCursor(other.m_platformCursor) +{ +} + +Cursor& Cursor::operator=(const Cursor& other) +{ + m_type = other.m_type; + m_image = other.m_image; + m_hotSpot = other.m_hotSpot; + m_platformCursor = other.m_platformCursor; + return *this; +} + +Cursor::~Cursor() +{ +} + +NSCursor *Cursor::platformCursor() const +{ + ensurePlatformCursor(); + return m_platformCursor.get(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/DragDataMac.mm b/Source/WebCore/platform/mac/DragDataMac.mm new file mode 100644 index 0000000..9cb4836 --- /dev/null +++ b/Source/WebCore/platform/mac/DragDataMac.mm @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#import "config.h" +#import "DragData.h" + +#if ENABLE(DRAG_SUPPORT) +#import "Document.h" +#import "DocumentFragment.h" +#import "DOMDocumentFragment.h" +#import "DOMDocumentFragmentInternal.h" +#import "MIMETypeRegistry.h" +#import "Pasteboard.h" +#import "PasteboardHelper.h" + +namespace WebCore { + +DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, + DragOperation sourceOperationMask, PasteboardHelper* pasteboardHelper) + : m_clientPosition(clientPosition) + , m_globalPosition(globalPosition) + , m_platformDragData(data) + , m_draggingSourceOperationMask(sourceOperationMask) + , m_pasteboardHelper(pasteboardHelper) +{ + ASSERT(pasteboardHelper); +} + +bool DragData::canSmartReplace() const +{ + //Need to call this so that the various Pasteboard type strings are intialised + Pasteboard::generalPasteboard(); + return [[[m_platformDragData draggingPasteboard] types] containsObject:WebSmartPastePboardType]; +} + +bool DragData::containsColor() const +{ + return [[[m_platformDragData draggingPasteboard] types] containsObject:NSColorPboardType]; +} + +bool DragData::containsFiles() const +{ + return [[[m_platformDragData draggingPasteboard] types] containsObject:NSFilenamesPboardType]; +} + +void DragData::asFilenames(Vector<String>& result) const +{ + NSArray *filenames = [[m_platformDragData draggingPasteboard] propertyListForType:NSFilenamesPboardType]; + NSEnumerator *fileEnumerator = [filenames objectEnumerator]; + + while (NSString *filename = [fileEnumerator nextObject]) + result.append(filename); +} + +bool DragData::containsPlainText() const +{ + NSPasteboard *pasteboard = [m_platformDragData draggingPasteboard]; + NSArray *types = [pasteboard types]; + + return [types containsObject:NSStringPboardType] + || [types containsObject:NSRTFDPboardType] + || [types containsObject:NSRTFPboardType] + || [types containsObject:NSFilenamesPboardType] + || [NSURL URLFromPasteboard:pasteboard]; +} + +String DragData::asPlainText() const +{ + return m_pasteboardHelper->plainTextFromPasteboard([m_platformDragData draggingPasteboard]); +} + +Color DragData::asColor() const +{ + NSColor *color = [NSColor colorFromPasteboard:[m_platformDragData draggingPasteboard]]; + return makeRGBA((int)([color redComponent] * 255.0 + 0.5), (int)([color greenComponent] * 255.0 + 0.5), + (int)([color blueComponent] * 255.0 + 0.5), (int)([color alphaComponent] * 255.0 + 0.5)); +} + +bool DragData::containsCompatibleContent() const +{ + NSPasteboard *pasteboard = [m_platformDragData draggingPasteboard]; + NSMutableSet *types = [NSMutableSet setWithArray:[pasteboard types]]; + [types intersectSet:[NSSet setWithArray:m_pasteboardHelper->insertablePasteboardTypes()]]; + return [types count] != 0; +} + +bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +{ + return !asURL(filenamePolicy).isEmpty(); +} + +String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +{ + // FIXME: Use filenamePolicy. + (void)filenamePolicy; + return m_pasteboardHelper->urlFromPasteboard([m_platformDragData draggingPasteboard], title); +} + +PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const +{ + return core(m_pasteboardHelper->fragmentFromPasteboard([m_platformDragData draggingPasteboard])); +} + +} // namespace WebCore + +#endif // ENABLE(DRAG_SUPPORT) diff --git a/Source/WebCore/platform/mac/DragImageMac.mm b/Source/WebCore/platform/mac/DragImageMac.mm new file mode 100644 index 0000000..f444b6e --- /dev/null +++ b/Source/WebCore/platform/mac/DragImageMac.mm @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2007, 2009 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. + */ + +#import "config.h" +#import "DragImage.h" + +#if ENABLE(DRAG_SUPPORT) +#import "CachedImage.h" +#import "Image.h" +#import "KURL.h" +#import "ResourceResponse.h" + +namespace WebCore { + +IntSize dragImageSize(RetainPtr<NSImage> image) +{ + return (IntSize)[image.get() size]; +} + +void deleteDragImage(RetainPtr<NSImage>) +{ + // Since this is a RetainPtr, there's nothing additional we need to do to + // delete it. It will be released when it falls out of scope. +} + +RetainPtr<NSImage> scaleDragImage(RetainPtr<NSImage> image, FloatSize scale) +{ + NSSize originalSize = [image.get() size]; + NSSize newSize = NSMakeSize((originalSize.width * scale.width()), (originalSize.height * scale.height())); + newSize.width = roundf(newSize.width); + newSize.height = roundf(newSize.height); + [image.get() setScalesWhenResized:YES]; + [image.get() setSize:newSize]; + return image; +} + +RetainPtr<NSImage> dissolveDragImageToFraction(RetainPtr<NSImage> image, float delta) +{ + RetainPtr<NSImage> dissolvedImage(AdoptNS, [[NSImage alloc] initWithSize:[image.get() size]]); + + NSPoint point = [image.get() isFlipped] ? NSMakePoint(0, [image.get() size].height) : NSZeroPoint; + + // In this case the dragging image is always correct. + [dissolvedImage.get() setFlipped:[image.get() isFlipped]]; + + [dissolvedImage.get() lockFocus]; + [image.get() dissolveToPoint:point fraction: delta]; + [dissolvedImage.get() unlockFocus]; + + [image.get() lockFocus]; + [dissolvedImage.get() compositeToPoint:point operation:NSCompositeCopy]; + [image.get() unlockFocus]; + + return image; +} + +RetainPtr<NSImage> createDragImageFromImage(Image* image) +{ + RetainPtr<NSImage> dragImage(AdoptNS, [image->getNSImage() copy]); + [dragImage.get() setSize:(NSSize)(image->size())]; + return dragImage; +} + +RetainPtr<NSImage> createDragImageIconForCachedImage(CachedImage* image) +{ + const String& filename = image->response().suggestedFilename(); + NSString *extension = nil; + size_t dotIndex = filename.reverseFind('.'); + + if (dotIndex != notFound && dotIndex < (filename.length() - 1)) // require that a . exists after the first character and before the last + extension = filename.substring(dotIndex + 1); + else { + // It might be worth doing a further lookup to pull the extension from the MIME type. + extension = @""; + } + + return [[NSWorkspace sharedWorkspace] iconForFileType:extension]; +} + +} // namespace WebCore + +#endif // ENABLE(DRAG_SUPPORT) diff --git a/Source/WebCore/platform/mac/EmptyProtocolDefinitions.h b/Source/WebCore/platform/mac/EmptyProtocolDefinitions.h new file mode 100644 index 0000000..b73177b --- /dev/null +++ b/Source/WebCore/platform/mac/EmptyProtocolDefinitions.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__OBJC__) + +#define EMPTY_PROTOCOL(NAME) \ +@protocol NAME <NSObject> \ +@end + +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + +EMPTY_PROTOCOL(NSTableViewDataSource) +EMPTY_PROTOCOL(NSTableViewDelegate) +EMPTY_PROTOCOL(NSWindowDelegate) + +#endif + +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) + +EMPTY_PROTOCOL(NSURLConnectionDelegate) +EMPTY_PROTOCOL(NSURLDownloadDelegate) + +#endif + +#undef EMPTY_PROTOCOL + +#endif /* defined(__OBJC__) */ diff --git a/Source/WebCore/platform/mac/EventLoopMac.mm b/Source/WebCore/platform/mac/EventLoopMac.mm new file mode 100644 index 0000000..4c3c8a4 --- /dev/null +++ b/Source/WebCore/platform/mac/EventLoopMac.mm @@ -0,0 +1,42 @@ +/* + * 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() +{ + // FIXME: Should this use NSRunLoopCommonModes? Switching to NSRunLoopCommonModes causes Safari to hang in a tight loop. + [NSApp setWindowsNeedUpdate:YES]; + NSTimeInterval interval = [[NSDate date] timeIntervalSinceReferenceDate]; + interval += 0.05; + NSDate *untilDate = [NSDate dateWithTimeIntervalSinceReferenceDate:interval]; + NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:untilDate inMode:NSDefaultRunLoopMode dequeue:YES]; + [NSApp sendEvent:event]; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/FileChooserMac.mm b/Source/WebCore/platform/mac/FileChooserMac.mm new file mode 100644 index 0000000..03532ff --- /dev/null +++ b/Source/WebCore/platform/mac/FileChooserMac.mm @@ -0,0 +1,55 @@ +/* + * 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. + * 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. + * + */ + +#import "config.h" +#import "FileChooser.h" + +#import "LocalizedStrings.h" +#import "SimpleFontData.h" +#import "StringTruncator.h" + +namespace WebCore { + +String FileChooser::basenameForWidth(const Font& font, int width) const +{ + if (width <= 0) + return String(); + + String strToTruncate; + if (m_filenames.isEmpty()) + strToTruncate = fileButtonNoFileSelectedLabel(); + else if (m_filenames.size() == 1) + strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(m_filenames[0])]; + else + return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false); + + return StringTruncator::centerTruncate(strToTruncate, width, font, false); +} + +} diff --git a/Source/WebCore/platform/mac/FileSystemMac.mm b/Source/WebCore/platform/mac/FileSystemMac.mm new file mode 100644 index 0000000..0df3c89 --- /dev/null +++ b/Source/WebCore/platform/mac/FileSystemMac.mm @@ -0,0 +1,65 @@ +/* + * 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. + */ +#import "config.h" +#import "FileSystem.h" + +#import "PlatformString.h" +#import <wtf/text/CString.h> + +namespace WebCore { + +String homeDirectoryPath() +{ + return NSHomeDirectory(); +} + +CString openTemporaryFile(const char* prefix, PlatformFileHandle& platformFileHandle) +{ + platformFileHandle = invalidPlatformFileHandle; + + Vector<char> temporaryFilePath(PATH_MAX); + if (!confstr(_CS_DARWIN_USER_TEMP_DIR, temporaryFilePath.data(), temporaryFilePath.size())) + return CString(); + + // Shrink the vector. + temporaryFilePath.shrink(strlen(temporaryFilePath.data())); + ASSERT(temporaryFilePath.last() == '/'); + + // Append the file name. + temporaryFilePath.append(prefix, strlen(prefix)); + temporaryFilePath.append("XXXXXX", 6); + temporaryFilePath.append('\0'); + + platformFileHandle = mkstemp(temporaryFilePath.data()); + if (platformFileHandle == invalidPlatformFileHandle) + return CString(); + + return CString(temporaryFilePath.data()); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/FoundationExtras.h b/Source/WebCore/platform/mac/FoundationExtras.h new file mode 100644 index 0000000..39b12ea --- /dev/null +++ b/Source/WebCore/platform/mac/FoundationExtras.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2004 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. + */ + +#import <CoreFoundation/CFBase.h> +#import <Foundation/NSObject.h> + +// Use HardAutorelease to return an object made by a CoreFoundation +// "create" or "copy" function as an autoreleased and garbage collected +// object. CF objects need to be "made collectable" for autorelease to work +// properly under GC. + +static inline id HardAutorelease(CFTypeRef object) +{ + if (object) + CFMakeCollectable(object); + [(id)object autorelease]; + return (id)object; +} diff --git a/Source/WebCore/platform/mac/KURLMac.mm b/Source/WebCore/platform/mac/KURLMac.mm new file mode 100644 index 0000000..c913ab4 --- /dev/null +++ b/Source/WebCore/platform/mac/KURLMac.mm @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2004, 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. + */ + +#import "config.h" +#import "KURL.h" + +#import "FoundationExtras.h" + +namespace WebCore { + +KURL::KURL(NSURL *url) +{ + if (!url) { + parse(0, 0); + return; + } + + CFIndex bytesLength = CFURLGetBytes(reinterpret_cast<CFURLRef>(url), 0, 0); + Vector<char, 512> buffer(bytesLength + 6); // 5 for "file:", 1 for null character to end C string + char* bytes = &buffer[5]; + CFURLGetBytes(reinterpret_cast<CFURLRef>(url), reinterpret_cast<UInt8*>(bytes), bytesLength); + bytes[bytesLength] = '\0'; + if (bytes[0] != '/') { + parse(bytes, 0); + return; + } + + buffer[0] = 'f'; + buffer[1] = 'i'; + buffer[2] = 'l'; + buffer[3] = 'e'; + buffer[4] = ':'; + + parse(buffer.data(), 0); +} + +KURL::operator NSURL *() const +{ + if (isNull()) + return nil; + + // CFURL can't hold an empty URL, unlike NSURL. + if (isEmpty()) + return [NSURL URLWithString:@""]; + + return HardAutorelease(createCFURL()); +} + +} diff --git a/Source/WebCore/platform/mac/KeyEventMac.mm b/Source/WebCore/platform/mac/KeyEventMac.mm new file mode 100644 index 0000000..30f1689 --- /dev/null +++ b/Source/WebCore/platform/mac/KeyEventMac.mm @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2004, 2006, 2007, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "PlatformKeyboardEvent.h" + +#if PLATFORM(MAC) + +#import "KeyEventCocoa.h" +#import "Logging.h" +#import "WindowsKeyboardCodes.h" +#import <Carbon/Carbon.h> + +using namespace WTF; + +namespace WebCore { + +static bool isKeypadEvent(NSEvent* event) +{ + // Check that this is the type of event that has a keyCode. + switch ([event type]) { + case NSKeyDown: + case NSKeyUp: + case NSFlagsChanged: + break; + default: + return false; + } + + if ([event modifierFlags] & NSNumericPadKeyMask) + return true; + + switch ([event keyCode]) { + case 71: // Clear + case 81: // = + case 75: // / + case 67: // * + case 78: // - + case 69: // + + case 76: // Enter + case 65: // . + case 82: // 0 + case 83: // 1 + case 84: // 2 + case 85: // 3 + case 86: // 4 + case 87: // 5 + case 88: // 6 + case 89: // 7 + case 91: // 8 + case 92: // 9 + return true; + } + + return false; +} + +static inline bool isKeyUpEvent(NSEvent *event) +{ + if ([event type] != NSFlagsChanged) + return [event type] == NSKeyUp; + // FIXME: This logic fails if the user presses both Shift keys at once, for example: + // we treat releasing one of them as keyDown. + switch ([event keyCode]) { + case 54: // Right Command + case 55: // Left Command + return ([event modifierFlags] & NSCommandKeyMask) == 0; + + case 57: // Capslock + return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0; + + case 56: // Left Shift + case 60: // Right Shift + return ([event modifierFlags] & NSShiftKeyMask) == 0; + + case 58: // Left Alt + case 61: // Right Alt + return ([event modifierFlags] & NSAlternateKeyMask) == 0; + + case 59: // Left Ctrl + case 62: // Right Ctrl + return ([event modifierFlags] & NSControlKeyMask) == 0; + + case 63: // Function + return ([event modifierFlags] & NSFunctionKeyMask) == 0; + } + return false; +} + +static inline String textFromEvent(NSEvent* event) +{ + if ([event type] == NSFlagsChanged) + return ""; + return [event characters]; +} + + +static inline String unmodifiedTextFromEvent(NSEvent* event) +{ + if ([event type] == NSFlagsChanged) + return ""; + return [event charactersIgnoringModifiers]; +} + +static String keyIdentifierForKeyEvent(NSEvent* event) +{ + if ([event type] == NSFlagsChanged) + switch ([event keyCode]) { + case 54: // Right Command + case 55: // Left Command + return "Meta"; + + case 57: // Capslock + return "CapsLock"; + + case 56: // Left Shift + case 60: // Right Shift + return "Shift"; + + case 58: // Left Alt + case 61: // Right Alt + return "Alt"; + + case 59: // Left Ctrl + case 62: // Right Ctrl + return "Control"; + + default: + ASSERT_NOT_REACHED(); + return ""; + } + + NSString *s = [event charactersIgnoringModifiers]; + if ([s length] != 1) { + LOG(Events, "received an unexpected number of characters in key event: %u", [s length]); + return "Unidentified"; + } + return keyIdentifierForCharCode([s characterAtIndex:0]); +} + +static int windowsKeyCodeForKeyEvent(NSEvent *event) +{ + int code = 0; + // There are several kinds of characters for which we produce key code from char code: + // 1. Roman letters. Windows keyboard layouts affect both virtual key codes and character codes for these, + // so e.g. 'A' gets the same keyCode on QWERTY, AZERTY or Dvorak layouts. + // 2. Keys for which there is no known Mac virtual key codes, like PrintScreen. + // 3. Certain punctuation keys. On Windows, these are also remapped depending on current keyboard layout, + // but see comment in windowsKeyCodeForCharCode(). + if ([event type] == NSKeyDown || [event type] == NSKeyUp) { + // Cmd switches Roman letters for Dvorak-QWERTY layout, so try modified characters first. + NSString* s = [event characters]; + code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0; + if (code) + return code; + + // Ctrl+A on an AZERTY keyboard would get VK_Q keyCode if we relied on -[NSEvent keyCode] below. + s = [event charactersIgnoringModifiers]; + code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0; + if (code) + return code; + } + + // Map Mac virtual key code directly to Windows one for any keys not handled above. + // E.g. the key next to Caps Lock has the same Event.keyCode on U.S. keyboard ('A') and on Russian keyboard (CYRILLIC LETTER EF). + return windowsKeyCodeForKeyCode([event keyCode]); +} + +PlatformKeyboardEvent::PlatformKeyboardEvent(NSEvent *event) + : m_type(isKeyUpEvent(event) ? PlatformKeyboardEvent::KeyUp : PlatformKeyboardEvent::KeyDown) + , m_text(textFromEvent(event)) + , m_unmodifiedText(unmodifiedTextFromEvent(event)) + , m_keyIdentifier(keyIdentifierForKeyEvent(event)) + , m_autoRepeat(([event type] != NSFlagsChanged) && [event isARepeat]) + , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(event)) + , m_nativeVirtualKeyCode([event keyCode]) + , m_isKeypad(isKeypadEvent(event)) + , m_shiftKey([event modifierFlags] & NSShiftKeyMask) + , m_ctrlKey([event modifierFlags] & NSControlKeyMask) + , m_altKey([event modifierFlags] & NSAlternateKeyMask) + , m_metaKey([event modifierFlags] & NSCommandKeyMask) + , m_macEvent(event) +{ + // Always use 13 for Enter/Return -- we don't want to use AppKit's different character for Enter. + if (m_windowsVirtualKeyCode == VK_RETURN) { + m_text = "\r"; + m_unmodifiedText = "\r"; + } + + // AppKit sets text to "\x7F" for backspace, but the correct KeyboardEvent character code is 8. + if (m_windowsVirtualKeyCode == VK_BACK) { + m_text = "\x8"; + m_unmodifiedText = "\x8"; + } + + // Always use 9 for Tab -- we don't want to use AppKit's different character for shift-tab. + if (m_windowsVirtualKeyCode == VK_TAB) { + m_text = "\x9"; + m_unmodifiedText = "\x9"; + } +} + +void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCompatibilityMode) +{ + // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions. + ASSERT(m_type == KeyDown); + ASSERT(type == RawKeyDown || type == Char); + m_type = type; + if (backwardCompatibilityMode) + return; + + if (type == RawKeyDown) { + m_text = String(); + m_unmodifiedText = String(); + } else { + m_keyIdentifier = String(); + m_windowsVirtualKeyCode = 0; + if (m_text.length() == 1 && (m_text[0U] >= 0xF700 && m_text[0U] <= 0xF7FF)) { + // According to NSEvents.h, OpenStep reserves the range 0xF700-0xF8FF for function keys. However, some actual private use characters + // happen to be in this range, e.g. the Apple logo (Option+Shift+K). + // 0xF7FF is an arbitrary cut-off. + m_text = String(); + m_unmodifiedText = String(); + } + } +} + +bool PlatformKeyboardEvent::currentCapsLockState() +{ + return GetCurrentKeyModifiers() & alphaLock; +} + +void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey) +{ + UInt32 currentModifiers = GetCurrentKeyModifiers(); + shiftKey = currentModifiers & ::shiftKey; + ctrlKey = currentModifiers & ::controlKey; + altKey = currentModifiers & ::optionKey; + metaKey = currentModifiers & ::cmdKey; +} + +} + +#endif // PLATFORM(MAC) diff --git a/Source/WebCore/platform/mac/KillRingMac.mm b/Source/WebCore/platform/mac/KillRingMac.mm new file mode 100644 index 0000000..32e7c72 --- /dev/null +++ b/Source/WebCore/platform/mac/KillRingMac.mm @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2010 Google Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "KillRing.h" + +namespace WebCore { + +extern "C" { + +// Kill ring calls. Would be better to use NSKillRing.h, but that's not available as API or SPI. + +void _NSInitializeKillRing(); +void _NSAppendToKillRing(NSString *); +void _NSPrependToKillRing(NSString *); +NSString *_NSYankFromKillRing(); +void _NSNewKillRingSequence(); +void _NSSetKillRingToYankedState(); + +} + +static void initializeKillRingIfNeeded() +{ + static bool initializedKillRing = false; + if (!initializedKillRing) { + initializedKillRing = true; + _NSInitializeKillRing(); + } +} + +void KillRing::append(const String& string) +{ + initializeKillRingIfNeeded(); + _NSAppendToKillRing(string); +} + +void KillRing::prepend(const String& string) +{ + initializeKillRingIfNeeded(); + _NSPrependToKillRing(string); +} + +String KillRing::yank() +{ + initializeKillRingIfNeeded(); + return _NSYankFromKillRing(); +} + +void KillRing::startNewSequence() +{ + initializeKillRingIfNeeded(); + _NSNewKillRingSequence(); +} + +void KillRing::setToYankedState() +{ + initializeKillRingIfNeeded(); + _NSSetKillRingToYankedState(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/Language.mm b/Source/WebCore/platform/mac/Language.mm new file mode 100644 index 0000000..c242e9e --- /dev/null +++ b/Source/WebCore/platform/mac/Language.mm @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2003, 2005, 2006, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "Language.h" + +#import "BlockExceptions.h" +#import "WebCoreSystemInterface.h" +#import <wtf/Assertions.h> +#import <wtf/MainThread.h> +#import <wtf/text/WTFString.h> + +using namespace WebCore; + +static NSString *preferredLanguageCode; + +@interface LanguageChangeObserver : NSObject { +} +@end + +@implementation LanguageChangeObserver + ++ (void)_webkit_languagePreferencesDidChange +{ + ASSERT(isMainThread()); + + [preferredLanguageCode release]; + preferredLanguageCode = nil; + + languageDidChange(); +} + +@end + +namespace WebCore { + +static NSString *createHTTPStyleLanguageCode(NSString *languageCode) +{ + ASSERT(isMainThread()); + + // Look up the language code using CFBundle. + CFStringRef preferredLanguageCode = wkCopyCFLocalizationPreferredName((CFStringRef)languageCode); + + if (preferredLanguageCode) + languageCode = (NSString *)preferredLanguageCode; + + // Make the string lowercase. + NSString *lowercaseLanguageCode = [languageCode lowercaseString]; + + NSString *httpStyleLanguageCode; + + // Turn a '_' into a '-' if it appears after a 2-letter language code. + if ([lowercaseLanguageCode length] >= 3 && [lowercaseLanguageCode characterAtIndex:2] == '_') { + NSMutableString *mutableLanguageCode = [lowercaseLanguageCode mutableCopy]; + [mutableLanguageCode replaceCharactersInRange:NSMakeRange(2, 1) withString:@"-"]; + httpStyleLanguageCode = mutableLanguageCode; + } else + httpStyleLanguageCode = [lowercaseLanguageCode retain]; + + if (preferredLanguageCode) + CFRelease(preferredLanguageCode); + + return httpStyleLanguageCode; +} + +String platformDefaultLanguage() +{ + ASSERT(isMainThread()); + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + if (!preferredLanguageCode) { + [[NSUserDefaults standardUserDefaults] synchronize]; + NSArray *languages = [[NSUserDefaults standardUserDefaults] stringArrayForKey:@"AppleLanguages"]; + if (![languages count]) + preferredLanguageCode = @"en"; + else + preferredLanguageCode = createHTTPStyleLanguageCode([languages objectAtIndex:0]); + } + + NSString *code = [[preferredLanguageCode retain] autorelease]; + + static bool languageChangeObserverAdded; + if (!languageChangeObserverAdded) { + [[NSDistributedNotificationCenter defaultCenter] addObserver:[LanguageChangeObserver self] + selector:@selector(_webkit_languagePreferencesDidChange) + name:@"AppleLanguagePreferencesChangedNotification" + object:nil]; + languageChangeObserverAdded = true; + } + + return code; + + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +} diff --git a/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h new file mode 100644 index 0000000..90beb40 --- /dev/null +++ b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <wtf/Noncopyable.h> + +#ifdef __OBJC__ +@class NSGraphicsContext; +#else +class NSGraphicsContext; +#endif + +namespace WebCore { + +class GraphicsContext; + +// This class automatically saves and restores the current NSGraphicsContext for +// functions which call out into AppKit and rely on the currentContext being set +class LocalCurrentGraphicsContext : public Noncopyable { +public: + LocalCurrentGraphicsContext(GraphicsContext* graphicsContext); + ~LocalCurrentGraphicsContext(); + +private: + GraphicsContext* m_savedGraphicsContext; + NSGraphicsContext* m_savedNSGraphicsContext; +}; + +} diff --git a/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm new file mode 100644 index 0000000..756d353 --- /dev/null +++ b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "LocalCurrentGraphicsContext.h" + +#include "GraphicsContext.h" +#include <AppKit/NSGraphicsContext.h> + +namespace WebCore { + +LocalCurrentGraphicsContext::LocalCurrentGraphicsContext(GraphicsContext* graphicsContext) +{ + m_savedGraphicsContext = graphicsContext; + graphicsContext->save(); + + if (graphicsContext->platformContext() == [[NSGraphicsContext currentContext] graphicsPort]) { + m_savedNSGraphicsContext = 0; + return; + } + + m_savedNSGraphicsContext = [[NSGraphicsContext currentContext] retain]; + NSGraphicsContext* newContext = [NSGraphicsContext graphicsContextWithGraphicsPort:graphicsContext->platformContext() flipped:YES]; + [NSGraphicsContext setCurrentContext:newContext]; +} + +LocalCurrentGraphicsContext::~LocalCurrentGraphicsContext() +{ + m_savedGraphicsContext->restore(); + + if (m_savedNSGraphicsContext) { + [NSGraphicsContext setCurrentContext:m_savedNSGraphicsContext]; + [m_savedNSGraphicsContext release]; + } +} + +} diff --git a/Source/WebCore/platform/mac/LoggingMac.mm b/Source/WebCore/platform/mac/LoggingMac.mm new file mode 100644 index 0000000..ee2f39e --- /dev/null +++ b/Source/WebCore/platform/mac/LoggingMac.mm @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2003, 2006 Apple Computer, 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 "Logging.h" + +namespace WebCore { + +static inline void initializeWithUserDefault(WTFLogChannel& channel) +{ + NSString *logLevelString = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithUTF8String:channel.defaultName]]; + if (logLevelString) { + unsigned logLevel; + if (![[NSScanner scannerWithString:logLevelString] scanHexInt:&logLevel]) + NSLog(@"unable to parse hex value for %s (%@), logging is off", channel.defaultName, logLevelString); + if ((logLevel & channel.mask) == channel.mask) + channel.state = WTFLogChannelOn; + else + channel.state = WTFLogChannelOff; + } +} + +void InitializeLoggingChannelsIfNecessary() +{ + static bool haveInitializedLoggingChannels = false; + if (haveInitializedLoggingChannels) + return; + haveInitializedLoggingChannels = true; + + initializeWithUserDefault(LogNotYetImplemented); + initializeWithUserDefault(LogFrames); + initializeWithUserDefault(LogLoading); + initializeWithUserDefault(LogPopupBlocking); + initializeWithUserDefault(LogEvents); + initializeWithUserDefault(LogEditing); + initializeWithUserDefault(LogLiveConnect); + initializeWithUserDefault(LogIconDatabase); + initializeWithUserDefault(LogSQLDatabase); + initializeWithUserDefault(LogSpellingAndGrammar); + initializeWithUserDefault(LogBackForward); + initializeWithUserDefault(LogHistory); + initializeWithUserDefault(LogPageCache); + initializeWithUserDefault(LogPlatformLeaks); + initializeWithUserDefault(LogResourceLoading); + initializeWithUserDefault(LogNetwork); + initializeWithUserDefault(LogFTP); + initializeWithUserDefault(LogThreading); + initializeWithUserDefault(LogStorageAPI); + initializeWithUserDefault(LogMedia); + initializeWithUserDefault(LogPlugins); + initializeWithUserDefault(LogArchives); +} + +} diff --git a/Source/WebCore/platform/mac/MIMETypeRegistryMac.mm b/Source/WebCore/platform/mac/MIMETypeRegistryMac.mm new file mode 100644 index 0000000..82348e0 --- /dev/null +++ b/Source/WebCore/platform/mac/MIMETypeRegistryMac.mm @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "MIMETypeRegistry.h" + +#include "WebCoreSystemInterface.h" + +namespace WebCore +{ + +String MIMETypeRegistry::getMIMETypeForExtension(const String &ext) +{ + return wkGetMIMETypeForExtension(ext); +} + +Vector<String> MIMETypeRegistry::getExtensionsForMIMEType(const String& type) +{ + NSArray *stringsArray = wkGetExtensionsForMIMEType(type); + Vector<String> stringsVector = Vector<String>(); + unsigned count = [stringsArray count]; + if (count > 0) { + NSEnumerator* enumerator = [stringsArray objectEnumerator]; + NSString* string; + while ((string = [enumerator nextObject]) != nil) + stringsVector.append(string); + } + return stringsVector; +} + +String MIMETypeRegistry::getPreferredExtensionForMIMEType(const String& type) +{ + return wkGetPreferredExtensionForMIMEType(type); +} + +bool MIMETypeRegistry::isApplicationPluginMIMEType(const String&) +{ + return false; +} + +} diff --git a/Source/WebCore/platform/mac/PasteboardHelper.h b/Source/WebCore/platform/mac/PasteboardHelper.h new file mode 100644 index 0000000..7bd62e5 --- /dev/null +++ b/Source/WebCore/platform/mac/PasteboardHelper.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PasteboardHelper_h +#define PasteboardHelper_h + +/* FIXME: This is a helper class used to provide access to functionality inside + * WebKit. The required functionality should eventually be migrated to WebCore + * so that this class can be removed. + */ +#if PLATFORM(MAC) + +#import <wtf/Forward.h> + +#ifdef __OBJC__ +@class DOMDocumentFragment; +#else +class DOMDocumentFragment; +#endif + +namespace WebCore { + + class Document; + + class PasteboardHelper { + public: + virtual ~PasteboardHelper() {} + virtual String urlFromPasteboard(NSPasteboard*, String* title) const = 0; + virtual String plainTextFromPasteboard(NSPasteboard*) const = 0; + virtual DOMDocumentFragment* fragmentFromPasteboard(NSPasteboard*) const = 0; + virtual NSArray* insertablePasteboardTypes() const = 0; + }; + +} +#endif // PLATFORM(MAC) + +#endif // !PasteboardHelper_h diff --git a/Source/WebCore/platform/mac/PasteboardMac.mm b/Source/WebCore/platform/mac/PasteboardMac.mm new file mode 100644 index 0000000..0625287 --- /dev/null +++ b/Source/WebCore/platform/mac/PasteboardMac.mm @@ -0,0 +1,562 @@ +/* + * Copyright (C) 2006 Apple Computer, 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. + */ + +#import "config.h" +#import "Pasteboard.h" + +#import "CachedResource.h" +#import "CharacterNames.h" +#import "DOMRangeInternal.h" +#import "Document.h" +#import "DocumentFragment.h" +#import "DocumentLoader.h" +#import "Editor.h" +#import "EditorClient.h" +#import "Frame.h" +#import "FrameLoaderClient.h" +#import "HitTestResult.h" +#import "HTMLAnchorElement.h" +#import "HTMLNames.h" +#import "Image.h" +#import "KURL.h" +#import "LegacyWebArchive.h" +#import "LoaderNSURLExtras.h" +#import "MIMETypeRegistry.h" +#import "Page.h" +#import "RenderImage.h" +#import "Text.h" +#import "WebCoreNSStringExtras.h" +#import "markup.h" + +#import <wtf/StdLibExtras.h> +#import <wtf/RetainPtr.h> +#import <wtf/UnusedParam.h> + +@interface NSAttributedString (AppKitSecretsIKnowAbout) +- (id)_initWithDOMRange:(DOMRange *)domRange; +@end + +namespace WebCore { + +// FIXME: It's not great to have these both here and in WebKit. +NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type"; +NSString *WebSmartPastePboardType = @"NeXT smart paste pasteboard type"; +NSString *WebURLNamePboardType = @"public.url-name"; +NSString *WebURLPboardType = @"public.url"; +NSString *WebURLsWithTitlesPboardType = @"WebURLsWithTitlesPboardType"; + +#ifndef BUILDING_ON_TIGER +static NSArray* selectionPasteboardTypes(bool canSmartCopyOrDelete, bool selectionContainsAttachments) +{ + if (selectionContainsAttachments) { + if (canSmartCopyOrDelete) + return [NSArray arrayWithObjects:WebSmartPastePboardType, WebArchivePboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, nil]; + else + return [NSArray arrayWithObjects:WebArchivePboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, nil]; + } else { // Don't write RTFD to the pasteboard when the copied attributed string has no attachments. + if (canSmartCopyOrDelete) + return [NSArray arrayWithObjects:WebSmartPastePboardType, WebArchivePboardType, NSRTFPboardType, NSStringPboardType, nil]; + else + return [NSArray arrayWithObjects:WebArchivePboardType, NSRTFPboardType, NSStringPboardType, nil]; + } +} +#endif + +static NSArray* writableTypesForURL() +{ + DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, types, ([[NSArray alloc] initWithObjects: + WebURLsWithTitlesPboardType, + NSURLPboardType, + WebURLPboardType, + WebURLNamePboardType, + NSStringPboardType, + nil])); + return types.get(); +} + +static inline NSArray* createWritableTypesForImage() +{ + NSMutableArray *types = [[NSMutableArray alloc] initWithObjects:NSTIFFPboardType, nil]; + [types addObjectsFromArray:writableTypesForURL()]; + [types addObject:NSRTFDPboardType]; + return types; +} + +static NSArray* writableTypesForImage() +{ + DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, types, (createWritableTypesForImage())); + return types.get(); +} + +Pasteboard* Pasteboard::generalPasteboard() +{ + static Pasteboard* pasteboard = new Pasteboard([NSPasteboard generalPasteboard]); + return pasteboard; +} + +Pasteboard::Pasteboard(NSPasteboard* pboard) + : m_pasteboard(pboard) +{ +} + +void Pasteboard::clear() +{ + [m_pasteboard.get() declareTypes:[NSArray array] owner:nil]; +} + +static NSAttributedString *stripAttachmentCharacters(NSAttributedString *string) +{ + const unichar attachmentCharacter = NSAttachmentCharacter; + DEFINE_STATIC_LOCAL(RetainPtr<NSString>, attachmentCharacterString, ([NSString stringWithCharacters:&attachmentCharacter length:1])); + NSMutableAttributedString *result = [[string mutableCopy] autorelease]; + NSRange attachmentRange = [[result string] rangeOfString:attachmentCharacterString.get()]; + while (attachmentRange.location != NSNotFound) { + [result replaceCharactersInRange:attachmentRange withString:@""]; + attachmentRange = [[result string] rangeOfString:attachmentCharacterString.get()]; + } + return result; +} + +void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) +{ + if (!WebArchivePboardType) + Pasteboard::generalPasteboard(); // Initializes pasteboard types. + ASSERT(selectedRange); + + NSAttributedString *attributedString = [[[NSAttributedString alloc] initWithString:selectedRange->text()] autorelease]; + +#ifdef BUILDING_ON_TIGER + // 4930197: Mail overrides [WebHTMLView pasteboardTypesForSelection] in order to add another type to the pasteboard + // after WebKit does. On Tiger we must call this function so that Mail code will be executed, meaning that + // we can't call WebCore::Pasteboard's method for setting types. + UNUSED_PARAM(canSmartCopyOrDelete); + + NSArray *types = frame->editor()->client()->pasteboardTypesForSelection(frame); + // Don't write RTFD to the pasteboard when the copied attributed string has no attachments. + NSMutableArray *mutableTypes = nil; + if (![attributedString containsAttachments]) { + mutableTypes = [[types mutableCopy] autorelease]; + [mutableTypes removeObject:NSRTFDPboardType]; + types = mutableTypes; + } + [pasteboard declareTypes:types owner:nil]; +#else + NSArray *types = selectionPasteboardTypes(canSmartCopyOrDelete, [attributedString containsAttachments]); + [pasteboard declareTypes:types owner:nil]; + frame->editor()->client()->didSetSelectionTypesForPasteboard(); +#endif + + // Put HTML on the pasteboard. + if ([types containsObject:WebArchivePboardType]) { + RefPtr<LegacyWebArchive> archive = LegacyWebArchive::createFromSelection(frame); + RetainPtr<CFDataRef> data = archive ? archive->rawDataRepresentation() : 0; + [pasteboard setData:(NSData *)data.get() forType:WebArchivePboardType]; + } + + // Put the attributed string on the pasteboard (RTF/RTFD format). + if ([types containsObject:NSRTFDPboardType]) { + NSData *RTFDData = [attributedString RTFDFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil]; + [pasteboard setData:RTFDData forType:NSRTFDPboardType]; + } + if ([types containsObject:NSRTFPboardType]) { + if ([attributedString containsAttachments]) + attributedString = stripAttachmentCharacters(attributedString); + NSData *RTFData = [attributedString RTFFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil]; + [pasteboard setData:RTFData forType:NSRTFPboardType]; + } + + // Put plain string on the pasteboard. + if ([types containsObject:NSStringPboardType]) { + // Map to a plain old space because this is better for source code, other browsers do it, + // and because HTML forces you to do this any time you want two spaces in a row. + String text = selectedRange->text(); + NSMutableString *s = [[[(NSString*)text copy] autorelease] mutableCopy]; + + NSString *NonBreakingSpaceString = [NSString stringWithCharacters:&noBreakSpace length:1]; + [s replaceOccurrencesOfString:NonBreakingSpaceString withString:@" " options:0 range:NSMakeRange(0, [s length])]; + [pasteboard setString:s forType:NSStringPboardType]; + [s release]; + } + + if ([types containsObject:WebSmartPastePboardType]) { + [pasteboard setData:nil forType:WebSmartPastePboardType]; + } +} + +void Pasteboard::writePlainText(NSPasteboard* pasteboard, const String& text) +{ + NSArray *types = [NSArray arrayWithObject:NSStringPboardType]; + [pasteboard declareTypes:types owner:nil]; + + [pasteboard setString:text forType:NSStringPboardType]; +} + +void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) +{ + Pasteboard::writeSelection(m_pasteboard.get(), selectedRange, canSmartCopyOrDelete, frame); +} + +void Pasteboard::writePlainText(const String& text) +{ + if (!WebArchivePboardType) + Pasteboard::generalPasteboard(); // Initializes pasteboard types. + + NSArray *types = [NSArray arrayWithObject:NSStringPboardType]; + NSPasteboard *pasteboard = m_pasteboard.get(); + [pasteboard declareTypes:types owner:nil]; + + [pasteboard setString:text forType:NSStringPboardType]; +} + +void Pasteboard::writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame) +{ + if (!WebArchivePboardType) + Pasteboard::generalPasteboard(); // Initializes pasteboard types. + + if (!types) { + types = writableTypesForURL(); + [pasteboard declareTypes:types owner:nil]; + } + + ASSERT(!url.isEmpty()); + + NSURL *cocoaURL = url; + NSString *userVisibleString = frame->editor()->client()->userVisibleString(cocoaURL); + + NSString *title = (NSString*)titleStr; + if ([title length] == 0) { + title = [[cocoaURL path] lastPathComponent]; + if ([title length] == 0) + title = userVisibleString; + } + + if ([types containsObject:WebURLsWithTitlesPboardType]) + [pasteboard setPropertyList:[NSArray arrayWithObjects:[NSArray arrayWithObject:userVisibleString], + [NSArray arrayWithObject:(NSString*)titleStr.stripWhiteSpace()], + nil] + forType:WebURLsWithTitlesPboardType]; + if ([types containsObject:NSURLPboardType]) + [cocoaURL writeToPasteboard:pasteboard]; + if ([types containsObject:WebURLPboardType]) + [pasteboard setString:userVisibleString forType:WebURLPboardType]; + if ([types containsObject:WebURLNamePboardType]) + [pasteboard setString:title forType:WebURLNamePboardType]; + if ([types containsObject:NSStringPboardType]) + [pasteboard setString:userVisibleString forType:NSStringPboardType]; +} + +void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame) +{ + Pasteboard::writeURL(m_pasteboard.get(), nil, url, titleStr, frame); +} + +static NSFileWrapper* fileWrapperForImage(CachedResource* resource, NSURL *url) +{ + SharedBuffer* coreData = resource->data(); + NSData *data = [[[NSData alloc] initWithBytes:coreData->data() length:coreData->size()] autorelease]; + NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease]; + String coreMIMEType = resource->response().mimeType(); + NSString *MIMEType = nil; + if (!coreMIMEType.isNull()) + MIMEType = coreMIMEType; + [wrapper setPreferredFilename:suggestedFilenameWithMIMEType(url, MIMEType)]; + return wrapper; +} + +void Pasteboard::writeFileWrapperAsRTFDAttachment(NSFileWrapper* wrapper) +{ + NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:wrapper]; + + NSAttributedString *string = [NSAttributedString attributedStringWithAttachment:attachment]; + [attachment release]; + + NSData *RTFDData = [string RTFDFromRange:NSMakeRange(0, [string length]) documentAttributes:nil]; + [m_pasteboard.get() setData:RTFDData forType:NSRTFDPboardType]; +} + +void Pasteboard::writeImage(Node* node, const KURL& url, const String& title) +{ + ASSERT(node); + Frame* frame = node->document()->frame(); + + NSURL *cocoaURL = url; + ASSERT(cocoaURL); + + ASSERT(node->renderer() && node->renderer()->isImage()); + RenderImage* renderer = toRenderImage(node->renderer()); + CachedImage* cachedImage = renderer->cachedImage(); + if (!cachedImage || cachedImage->errorOccurred()) + return; + + NSArray* types = writableTypesForImage(); + [m_pasteboard.get() declareTypes:types owner:nil]; + writeURL(m_pasteboard.get(), types, cocoaURL, nsStringNilIfEmpty(title), frame); + + Image* image = cachedImage->image(); + ASSERT(image); + + [m_pasteboard.get() setData:[image->getNSImage() TIFFRepresentation] forType:NSTIFFPboardType]; + + String MIMEType = cachedImage->response().mimeType(); + ASSERT(MIMETypeRegistry::isSupportedImageResourceMIMEType(MIMEType)); + + writeFileWrapperAsRTFDAttachment(fileWrapperForImage(cachedImage, cocoaURL)); +} + +bool Pasteboard::canSmartReplace() +{ + return [[m_pasteboard.get() types] containsObject:WebSmartPastePboardType]; +} + +String Pasteboard::plainText(Frame* frame) +{ + NSArray *types = [m_pasteboard.get() types]; + + if ([types containsObject:NSStringPboardType]) + return [[m_pasteboard.get() stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping]; + + NSAttributedString *attributedString = nil; + NSString *string; + + if ([types containsObject:NSRTFDPboardType]) + attributedString = [[NSAttributedString alloc] initWithRTFD:[m_pasteboard.get() dataForType:NSRTFDPboardType] documentAttributes:NULL]; + if (attributedString == nil && [types containsObject:NSRTFPboardType]) + attributedString = [[NSAttributedString alloc] initWithRTF:[m_pasteboard.get() dataForType:NSRTFPboardType] documentAttributes:NULL]; + if (attributedString != nil) { + string = [[attributedString string] precomposedStringWithCanonicalMapping]; + [attributedString release]; + return string; + } + + if ([types containsObject:NSFilenamesPboardType]) { + string = [[[m_pasteboard.get() propertyListForType:NSFilenamesPboardType] componentsJoinedByString:@"\n"] precomposedStringWithCanonicalMapping]; + if (string != nil) + return string; + } + + + if (NSURL *url = [NSURL URLFromPasteboard:m_pasteboard.get()]) { + // FIXME: using the editorClient to call into webkit, for now, since + // calling _web_userVisibleString from WebCore involves migrating a sizable web of + // helper code that should either be done in a separate patch or figured out in another way. + string = frame->editor()->client()->userVisibleString(url); + if ([string length] > 0) + return [string precomposedStringWithCanonicalMapping]; + } + + + return String(); +} + +PassRefPtr<DocumentFragment> Pasteboard::documentFragmentWithImageResource(Frame* frame, PassRefPtr<ArchiveResource> resource) +{ + if (DocumentLoader* loader = frame->loader()->documentLoader()) + loader->addArchiveResource(resource.get()); + + RefPtr<Element> imageElement = frame->document()->createElement(HTMLNames::imgTag, false); + if (!imageElement) + return 0; + + NSURL *URL = resource->url(); + imageElement->setAttribute(HTMLNames::srcAttr, [URL isFileURL] ? [URL absoluteString] : resource->url()); + RefPtr<DocumentFragment> fragment = frame->document()->createDocumentFragment(); + if (fragment) { + ExceptionCode ec; + fragment->appendChild(imageElement, ec); + return fragment.release(); + } + return 0; +} + +PassRefPtr<DocumentFragment> Pasteboard::documentFragmentWithRtf(Frame* frame, NSString* pboardType) +{ + if (!frame || !frame->document() || !frame->document()->isHTMLDocument()) + return 0; + + NSAttributedString *string = nil; + if (pboardType == NSRTFDPboardType) + string = [[NSAttributedString alloc] initWithRTFD:[m_pasteboard.get() dataForType:NSRTFDPboardType] documentAttributes:NULL]; + if (string == nil) + string = [[NSAttributedString alloc] initWithRTF:[m_pasteboard.get() dataForType:NSRTFPboardType] documentAttributes:NULL]; + if (string == nil) + return nil; + + bool wasDeferringCallbacks = frame->page()->defersLoading(); + if (!wasDeferringCallbacks) + frame->page()->setDefersLoading(true); + + Vector<RefPtr<ArchiveResource> > resources; + RefPtr<DocumentFragment> fragment = frame->editor()->client()->documentFragmentFromAttributedString(string, resources); + + size_t size = resources.size(); + if (size) { + DocumentLoader* loader = frame->loader()->documentLoader(); + for (size_t i = 0; i < size; ++i) + loader->addArchiveResource(resources[i]); + } + + if (!wasDeferringCallbacks) + frame->page()->setDefersLoading(false); + + [string release]; + return fragment.release(); +} + +#define WebDataProtocolScheme @"webkit-fake-url" + +static NSURL* uniqueURLWithRelativePart(NSString *relativePart) +{ + CFUUIDRef UUIDRef = CFUUIDCreate(kCFAllocatorDefault); + NSString *UUIDString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, UUIDRef); + CFRelease(UUIDRef); + NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@/%@", WebDataProtocolScheme, UUIDString, relativePart]]; + CFRelease(UUIDString); + + return URL; +} + +PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) +{ + NSArray *types = [m_pasteboard.get() types]; + RefPtr<DocumentFragment> fragment; + chosePlainText = false; + + if ([types containsObject:WebArchivePboardType]) { + RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData([m_pasteboard.get() dataForType:WebArchivePboardType]).get()); + if (coreArchive) { + RefPtr<ArchiveResource> mainResource = coreArchive->mainResource(); + if (mainResource) { + NSString *MIMEType = mainResource->mimeType(); + if (!frame || !frame->document()) + return 0; + if (frame->loader()->client()->canShowMIMETypeAsHTML(MIMEType)) { + NSString *markupString = [[NSString alloc] initWithData:[mainResource->data()->createNSData() autorelease] encoding:NSUTF8StringEncoding]; + // FIXME: seems poor form to do this as a side effect of getting a document fragment + if (DocumentLoader* loader = frame->loader()->documentLoader()) + loader->addAllArchiveResources(coreArchive.get()); + + fragment = createFragmentFromMarkup(frame->document(), markupString, mainResource->url(), FragmentScriptingNotAllowed); + [markupString release]; + } else if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType)) + fragment = documentFragmentWithImageResource(frame, mainResource); + } + } + if (fragment) + return fragment.release(); + } + + if ([types containsObject:NSFilenamesPboardType]) { + NSArray* paths = [m_pasteboard.get() propertyListForType:NSFilenamesPboardType]; + NSEnumerator* enumerator = [paths objectEnumerator]; + NSString* path; + Vector< RefPtr<Node> > refNodesVector; + Vector<Node*> nodesVector; + + while ((path = [enumerator nextObject]) != nil) { + // Non-image file types; _web_userVisibleString is appropriate here because this will + // be pasted as visible text. + NSString *url = frame->editor()->client()->userVisibleString([NSURL fileURLWithPath:path]); + RefPtr<Node> textNode = frame->document()->createTextNode(url); + refNodesVector.append(textNode.get()); + nodesVector.append(textNode.get()); + } + fragment = createFragmentFromNodes(frame->document(), nodesVector); + if (fragment && fragment->firstChild()) + return fragment.release(); + } + + if ([types containsObject:NSHTMLPboardType]) { + NSString *HTMLString = [m_pasteboard.get() stringForType:NSHTMLPboardType]; + // This is a hack to make Microsoft's HTML pasteboard data work. See 3778785. + if ([HTMLString hasPrefix:@"Version:"]) { + NSRange range = [HTMLString rangeOfString:@"<html" options:NSCaseInsensitiveSearch]; + if (range.location != NSNotFound) { + HTMLString = [HTMLString substringFromIndex:range.location]; + } + } + if ([HTMLString length] != 0 && + (fragment = createFragmentFromMarkup(frame->document(), HTMLString, "", FragmentScriptingNotAllowed))) + return fragment.release(); + } + + if ([types containsObject:NSRTFDPboardType] && + (fragment = documentFragmentWithRtf(frame, NSRTFDPboardType))) + return fragment.release(); + + if ([types containsObject:NSRTFPboardType] && + (fragment = documentFragmentWithRtf(frame, NSRTFPboardType))) + return fragment.release(); + + if ([types containsObject:NSTIFFPboardType] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSTIFFPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"image.tiff"), "image/tiff", "", "")))) + return fragment.release(); + + if ([types containsObject:NSPDFPboardType] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSPDFPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"application.pdf"), "application/pdf", "", "")))) + return fragment.release(); + +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + if ([types containsObject:NSPICTPboardType] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:NSPICTPboardType] copy] autorelease]), uniqueURLWithRelativePart(@"image.pict"), "image/pict", "", "")))) + return fragment.release(); +#endif + + // Only 10.5 and higher support setting and retrieving pasteboard types with UTIs, but we don't believe + // that any applications on Tiger put types for which we only have a UTI, like PNG, on the pasteboard. + if ([types containsObject:(NSString*)kUTTypePNG] && + (fragment = documentFragmentWithImageResource(frame, ArchiveResource::create(SharedBuffer::wrapNSData([[[m_pasteboard.get() dataForType:(NSString*)kUTTypePNG] copy] autorelease]), uniqueURLWithRelativePart(@"image.png"), "image/png", "", "")))) + return fragment.release(); + + if ([types containsObject:NSURLPboardType]) { + NSURL *URL = [NSURL URLFromPasteboard:m_pasteboard.get()]; + Document* document = frame->document(); + ASSERT(document); + if (!document) + return 0; + RefPtr<Element> anchor = document->createElement(HTMLNames::aTag, false); + NSString *URLString = [URL absoluteString]; // Original data is ASCII-only, so there is no need to precompose. + if ([URLString length] == 0) + return nil; + NSString *URLTitleString = [[m_pasteboard.get() stringForType:WebURLNamePboardType] precomposedStringWithCanonicalMapping]; + ExceptionCode ec; + anchor->setAttribute(HTMLNames::hrefAttr, URLString); + anchor->appendChild(document->createTextNode(URLTitleString), ec); + fragment = document->createDocumentFragment(); + if (fragment) { + fragment->appendChild(anchor, ec); + return fragment.release(); + } + } + + if (allowPlainText && [types containsObject:NSStringPboardType]) { + chosePlainText = true; + fragment = createFragmentFromText(context.get(), [[m_pasteboard.get() stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping]); + return fragment.release(); + } + + return 0; +} + +} diff --git a/Source/WebCore/platform/mac/PlatformMouseEventMac.mm b/Source/WebCore/platform/mac/PlatformMouseEventMac.mm new file mode 100644 index 0000000..5b84b4f --- /dev/null +++ b/Source/WebCore/platform/mac/PlatformMouseEventMac.mm @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2004, 2006 Apple Computer, 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. + */ + +#import "config.h" +#import "PlatformMouseEvent.h" + +#import "PlatformScreen.h" + +namespace WebCore { + +static MouseButton mouseButtonForEvent(NSEvent *event) +{ + switch ([event type]) { + case NSLeftMouseDown: + case NSLeftMouseUp: + case NSLeftMouseDragged: + return LeftButton; + case NSRightMouseDown: + case NSRightMouseUp: + case NSRightMouseDragged: + return RightButton; + case NSOtherMouseDown: + case NSOtherMouseUp: + case NSOtherMouseDragged: + return MiddleButton; + default: + return NoButton; + } +} + +static int clickCountForEvent(NSEvent *event) +{ + switch ([event type]) { + case NSLeftMouseDown: + case NSLeftMouseUp: + case NSLeftMouseDragged: + case NSRightMouseDown: + case NSRightMouseUp: + case NSRightMouseDragged: + case NSOtherMouseDown: + case NSOtherMouseUp: + case NSOtherMouseDragged: + return [event clickCount]; + default: + return 0; + } +} + +IntPoint globalPoint(const NSPoint& windowPoint, NSWindow *window) +{ + return IntPoint(flipScreenPoint([window convertBaseToScreen:windowPoint], screenForWindow(window))); +} + +IntPoint pointForEvent(NSEvent *event, NSView *windowView) +{ + switch ([event type]) { + case NSLeftMouseDown: + case NSLeftMouseUp: + case NSLeftMouseDragged: + case NSRightMouseDown: + case NSRightMouseUp: + case NSRightMouseDragged: + case NSOtherMouseDown: + case NSOtherMouseUp: + case NSOtherMouseDragged: + case NSMouseMoved: + case NSScrollWheel: { + // Note: This will have its origin at the bottom left of the window unless windowView is flipped. + // In those cases, the Y coordinate gets flipped by Widget::convertFromContainingWindow. + NSPoint location = [event locationInWindow]; + if (windowView) + location = [windowView convertPoint:location fromView:nil]; + return IntPoint(location); + } + default: + return IntPoint(); + } +} + +IntPoint globalPointForEvent(NSEvent *event) +{ + switch ([event type]) { + case NSLeftMouseDown: + case NSLeftMouseUp: + case NSLeftMouseDragged: + case NSRightMouseDown: + case NSRightMouseUp: + case NSRightMouseDragged: + case NSOtherMouseDown: + case NSOtherMouseUp: + case NSOtherMouseDragged: + case NSMouseMoved: + case NSScrollWheel: + return globalPoint([event locationInWindow], [event window]); + default: + return IntPoint(); + } +} + +static MouseEventType mouseEventForNSEvent(NSEvent* event) +{ + switch ([event type]) { + case NSScrollWheel: + return MouseEventScroll; + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + case NSMouseMoved: + return MouseEventMoved; + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + return MouseEventPressed; + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + return MouseEventReleased; + default: + return MouseEventMoved; + } +} + +PlatformMouseEvent::PlatformMouseEvent(NSEvent* event, NSView *windowView) + : m_position(pointForEvent(event, windowView)) + , m_globalPosition(globalPointForEvent(event)) + , m_button(mouseButtonForEvent(event)) + , m_eventType(mouseEventForNSEvent(event)) + , m_clickCount(clickCountForEvent(event)) + , m_shiftKey([event modifierFlags] & NSShiftKeyMask) + , m_ctrlKey([event modifierFlags] & NSControlKeyMask) + , m_altKey([event modifierFlags] & NSAlternateKeyMask) + , m_metaKey([event modifierFlags] & NSCommandKeyMask) + , m_timestamp([event timestamp]) + , m_modifierFlags([event modifierFlags]) + , m_eventNumber([event eventNumber]) +{ +} + +PlatformMouseEvent::PlatformMouseEvent(int x, int y, int globalX, int globalY, MouseButton button, MouseEventType eventType, + int clickCount, bool shiftKey, bool ctrlKey, bool altKey, bool metaKey, double timestamp, + unsigned modifierFlags, int eventNumber) + : m_position(IntPoint(x, y)) + , m_globalPosition(IntPoint(globalX, globalY)) + , m_button(button) + , m_eventType(eventType) + , m_clickCount(clickCount) + , m_shiftKey(shiftKey) + , m_ctrlKey(ctrlKey) + , m_altKey(altKey) + , m_metaKey(metaKey) + , m_timestamp(timestamp) + , m_modifierFlags(modifierFlags) + , m_eventNumber(eventNumber) +{ +} + +} diff --git a/Source/WebCore/platform/mac/PlatformScreenMac.mm b/Source/WebCore/platform/mac/PlatformScreenMac.mm new file mode 100644 index 0000000..5dbfcf4 --- /dev/null +++ b/Source/WebCore/platform/mac/PlatformScreenMac.mm @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2006 Apple Computer, 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. + */ + +#import "config.h" +#import "PlatformScreen.h" + +#import "FloatRect.h" +#import "Frame.h" +#import "FrameView.h" +#import "Page.h" + +namespace WebCore { + +int screenDepth(Widget*) +{ + return NSBitsPerPixelFromDepth([[NSScreen deepestScreen] depth]); +} + +int screenDepthPerComponent(Widget*) +{ + return NSBitsPerSampleFromDepth([[NSScreen deepestScreen] depth]); +} + +bool screenIsMonochrome(Widget*) +{ + return false; +} + +// These functions scale between screen and page coordinates because JavaScript/DOM operations +// assume that the screen and the page share the same coordinate system. + +FloatRect screenRect(Widget* widget) +{ + NSWindow *window = widget ? [widget->platformWidget() window] : nil; + return toUserSpace([screenForWindow(window) frame], window); +} + +FloatRect screenAvailableRect(Widget* widget) +{ + NSWindow *window = widget ? [widget->platformWidget() window] : nil; + return toUserSpace([screenForWindow(window) visibleFrame], window); +} + +NSScreen *screenForWindow(NSWindow *window) +{ + NSScreen *screen = [window screen]; // nil if the window is off-screen + if (screen) + return screen; + + NSArray *screens = [NSScreen screens]; + if ([screens count] > 0) + return [screens objectAtIndex:0]; // screen containing the menubar + + return nil; +} + +FloatRect toUserSpace(const NSRect& rect, NSWindow *destination) +{ + FloatRect userRect = rect; + userRect.setY(NSMaxY([screenForWindow(destination) frame]) - (userRect.y() + userRect.height())); // flip + if (destination) + userRect.scale(1 / [destination userSpaceScaleFactor]); // scale down + return userRect; +} + +NSRect toDeviceSpace(const FloatRect& rect, NSWindow *source) +{ + FloatRect deviceRect = rect; + if (source) + deviceRect.scale([source userSpaceScaleFactor]); // scale up + deviceRect.setY(NSMaxY([screenForWindow(source) frame]) - (deviceRect.y() + deviceRect.height())); // flip + return deviceRect; +} + +NSPoint flipScreenPoint(const NSPoint& screenPoint, NSScreen *screen) +{ + NSPoint flippedPoint = screenPoint; + flippedPoint.y = NSMaxY([screen frame]) - flippedPoint.y; + return flippedPoint; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/PopupMenuMac.h b/Source/WebCore/platform/mac/PopupMenuMac.h new file mode 100644 index 0000000..8e21913 --- /dev/null +++ b/Source/WebCore/platform/mac/PopupMenuMac.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef PopupMenuMac_h +#define PopupMenuMac_h + +#include "IntRect.h" +#include "PopupMenu.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RetainPtr.h> + +#ifdef __OBJC__ +@class NSPopUpButtonCell; +#else +class NSPopUpButtonCell; +#endif + +namespace WebCore { + +class PopupMenuClient; +class FrameView; +class Scrollbar; + +class PopupMenuMac : public PopupMenu { +public: + PopupMenuMac(PopupMenuClient*); + ~PopupMenuMac(); + + virtual void show(const IntRect&, FrameView*, int index); + virtual void hide(); + virtual void updateFromElement(); + virtual void disconnectClient(); + +private: + void clear(); + void populate(); + PopupMenuClient* client() const { return m_popupClient; } + + PopupMenuClient* m_popupClient; + RetainPtr<NSPopUpButtonCell> m_popup; +}; + +} + +#endif // PopupMenuMac_h diff --git a/Source/WebCore/platform/mac/PopupMenuMac.mm b/Source/WebCore/platform/mac/PopupMenuMac.mm new file mode 100644 index 0000000..1bf500b --- /dev/null +++ b/Source/WebCore/platform/mac/PopupMenuMac.mm @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#import "config.h" +#import "PopupMenuMac.h" + +#import "AXObjectCache.h" +#import "Chrome.h" +#import "ChromeClient.h" +#import "EventHandler.h" +#import "Frame.h" +#import "FrameView.h" +#import "HTMLNames.h" +#import "HTMLOptGroupElement.h" +#import "HTMLOptionElement.h" +#import "HTMLSelectElement.h" +#import "Page.h" +#import "PopupMenuClient.h" +#import "SimpleFontData.h" +#import "WebCoreSystemInterface.h" + +namespace WebCore { + +using namespace HTMLNames; + +PopupMenuMac::PopupMenuMac(PopupMenuClient* client) + : m_popupClient(client) +{ +} + +PopupMenuMac::~PopupMenuMac() +{ + if (m_popup) + [m_popup.get() setControlView:nil]; +} + +void PopupMenuMac::clear() +{ + if (m_popup) + [m_popup.get() removeAllItems]; +} + +void PopupMenuMac::populate() +{ + if (m_popup) + clear(); + else { + m_popup = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:!client()->shouldPopOver()]; + [m_popup.get() release]; // release here since the RetainPtr has retained the object already + [m_popup.get() setUsesItemFromMenu:NO]; + [m_popup.get() setAutoenablesItems:NO]; + } + + BOOL messagesEnabled = [[m_popup.get() menu] menuChangedMessagesEnabled]; + [[m_popup.get() menu] setMenuChangedMessagesEnabled:NO]; + + // For pullDown menus the first item is hidden. + if (!client()->shouldPopOver()) + [m_popup.get() addItemWithTitle:@""]; + + ASSERT(client()); + int size = client()->listSize(); + + for (int i = 0; i < size; i++) { + if (client()->itemIsSeparator(i)) + [[m_popup.get() menu] addItem:[NSMenuItem separatorItem]]; + else { + PopupMenuStyle style = client()->itemStyle(i); + NSMutableDictionary* attributes = [[NSMutableDictionary alloc] init]; + if (style.font() != Font()) { + NSFont *font = style.font().primaryFont()->getNSFont(); + if (!font) { + CGFloat size = style.font().primaryFont()->platformData().size(); + font = style.font().weight() < FontWeightBold ? [NSFont systemFontOfSize:size] : [NSFont boldSystemFontOfSize:size]; + } + [attributes setObject:font forKey:NSFontAttributeName]; + } + // FIXME: Add support for styling the foreground and background colors. + // FIXME: Find a way to customize text color when an item is highlighted. + NSAttributedString* string = [[NSAttributedString alloc] initWithString:client()->itemText(i) attributes:attributes]; + [attributes release]; + + [m_popup.get() addItemWithTitle:@""]; + NSMenuItem* menuItem = [m_popup.get() lastItem]; + [menuItem setAttributedTitle:string]; + [menuItem setEnabled:client()->itemIsEnabled(i)]; + [menuItem setToolTip:client()->itemToolTip(i)]; + [string release]; + + // Allow the accessible text of the item to be overriden if necessary. + if (AXObjectCache::accessibilityEnabled()) { + NSString *accessibilityOverride = client()->itemAccessibilityText(i); + if ([accessibilityOverride length]) + [menuItem accessibilitySetOverrideValue:accessibilityOverride forAttribute:NSAccessibilityDescriptionAttribute]; + } + } + } + + [[m_popup.get() menu] setMenuChangedMessagesEnabled:messagesEnabled]; +} + +void PopupMenuMac::show(const IntRect& r, FrameView* v, int index) +{ + populate(); + int numItems = [m_popup.get() numberOfItems]; + if (numItems <= 0) { + if (client()) + client()->popupDidHide(); + return; + } + ASSERT(numItems > index); + + // Workaround for crazy bug where a selected index of -1 for a menu with only 1 item will cause a blank menu. + if (index == -1 && numItems == 2 && !client()->shouldPopOver() && ![[m_popup.get() itemAtIndex:1] isEnabled]) + index = 0; + + NSView* view = v->documentView(); + + [m_popup.get() attachPopUpWithFrame:r inView:view]; + [m_popup.get() selectItemAtIndex:index]; + + NSMenu* menu = [m_popup.get() menu]; + + NSPoint location; + NSFont* font = client()->menuStyle().font().primaryFont()->getNSFont(); + + // These values were borrowed from AppKit to match their placement of the menu. + const int popOverHorizontalAdjust = -10; + const int popUnderHorizontalAdjust = 6; + const int popUnderVerticalAdjust = 6; + if (client()->shouldPopOver()) { + NSRect titleFrame = [m_popup.get() titleRectForBounds:r]; + if (titleFrame.size.width <= 0 || titleFrame.size.height <= 0) + titleFrame = r; + float vertOffset = roundf((NSMaxY(r) - NSMaxY(titleFrame)) + NSHeight(titleFrame)); + // Adjust for fonts other than the system font. + NSFont* defaultFont = [NSFont systemFontOfSize:[font pointSize]]; + vertOffset += [font descender] - [defaultFont descender]; + vertOffset = fminf(NSHeight(r), vertOffset); + + location = NSMakePoint(NSMinX(r) + popOverHorizontalAdjust, NSMaxY(r) - vertOffset); + } else + location = NSMakePoint(NSMinX(r) + popUnderHorizontalAdjust, NSMaxY(r) + popUnderVerticalAdjust); + + // Save the current event that triggered the popup, so we can clean up our event + // state after the NSMenu goes away. + RefPtr<Frame> frame = v->frame(); + NSEvent* event = [frame->eventHandler()->currentNSEvent() retain]; + + RefPtr<PopupMenuMac> protector(this); + + RetainPtr<NSView> dummyView(AdoptNS, [[NSView alloc] initWithFrame:r]); + [view addSubview:dummyView.get()]; + location = [dummyView.get() convertPoint:location fromView:view]; + + if (Page* page = frame->page()) + page->chrome()->client()->willPopUpMenu(menu); + wkPopupMenu(menu, location, roundf(NSWidth(r)), dummyView.get(), index, font); + + [m_popup.get() dismissPopUp]; + [dummyView.get() removeFromSuperview]; + + if (client()) { + int newIndex = [m_popup.get() indexOfSelectedItem]; + client()->popupDidHide(); + + // Adjust newIndex for hidden first item. + if (!client()->shouldPopOver()) + newIndex--; + + if (index != newIndex && newIndex >= 0) + client()->valueChanged(newIndex); + + // Give the frame a chance to fix up its event state, since the popup eats all the + // events during tracking. + frame->eventHandler()->sendFakeEventsAfterWidgetTracking(event); + } + + [event release]; +} + +void PopupMenuMac::hide() +{ + [m_popup.get() dismissPopUp]; +} + +void PopupMenuMac::updateFromElement() +{ +} + +void PopupMenuMac::disconnectClient() +{ + m_popupClient = 0; +} + +} diff --git a/Source/WebCore/platform/mac/PurgeableBufferMac.cpp b/Source/WebCore/platform/mac/PurgeableBufferMac.cpp new file mode 100644 index 0000000..fdbac1f --- /dev/null +++ b/Source/WebCore/platform/mac/PurgeableBufferMac.cpp @@ -0,0 +1,156 @@ +/* + * 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" + +#if ENABLE(PURGEABLE_MEMORY) + +#include "PurgeableBuffer.h" + +#include <mach/mach.h> +#include <wtf/Assertions.h> +#include <wtf/VMTags.h> + +namespace WebCore { + +// Purgeable buffers are allocated in multiples of the page size (4KB in common CPUs) so +// it does not make sense for very small buffers. Set our minimum size to 16KB. +static const size_t minPurgeableBufferSize = 4 * 4096; + +PurgeableBuffer::PurgeableBuffer(char* data, size_t size) + : m_data(data) + , m_size(size) + , m_purgePriority(PurgeDefault) + , m_state(NonVolatile) +{ +} + +PurgeableBuffer::~PurgeableBuffer() +{ + vm_deallocate(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), m_size); +} + +PassOwnPtr<PurgeableBuffer> PurgeableBuffer::create(const char* data, size_t size) +{ + if (size < minPurgeableBufferSize) + return PassOwnPtr<PurgeableBuffer>(); + + vm_address_t buffer = 0; + kern_return_t ret = vm_allocate(mach_task_self(), &buffer, size, VM_FLAGS_PURGABLE | VM_FLAGS_ANYWHERE | VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY); + + ASSERT(ret == KERN_SUCCESS); + if (ret != KERN_SUCCESS) + return PassOwnPtr<PurgeableBuffer>(); + + ret = vm_copy(mach_task_self(), reinterpret_cast<vm_address_t>(data), size, buffer); + + ASSERT(ret == KERN_SUCCESS); + if (ret != KERN_SUCCESS) { + vm_deallocate(mach_task_self(), buffer, size); + return PassOwnPtr<PurgeableBuffer>(); + } + + return adoptPtr(new PurgeableBuffer(reinterpret_cast<char*>(buffer), size)); +} + +bool PurgeableBuffer::makePurgeable(bool purgeable) +{ + if (purgeable) { + if (m_state != NonVolatile) + return true; + + int volatileGroup; + if (m_purgePriority == PurgeFirst) + volatileGroup = VM_VOLATILE_GROUP_0; + else if (m_purgePriority == PurgeMiddle) + volatileGroup = VM_VOLATILE_GROUP_4; + else + volatileGroup = VM_VOLATILE_GROUP_7; + + int state = VM_PURGABLE_VOLATILE | volatileGroup; + // So apparently "purgeable" is the correct spelling and the API here is misspelled. + kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_SET_STATE, &state); + + if (ret != KERN_SUCCESS) { + // If that failed we have no clue what state we are in so assume purged. + m_state = Purged; + return true; + } + + m_state = Volatile; + return true; + } + + if (m_state == NonVolatile) + return true; + if (m_state == Purged) + return false; + + int state = VM_PURGABLE_NONVOLATILE; + kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_SET_STATE, &state); + + if (ret != KERN_SUCCESS) { + // If that failed we have no clue what state we are in so assume purged. + m_state = Purged; + return false; + } + + m_state = state & VM_PURGABLE_EMPTY ? Purged : NonVolatile; + return m_state == NonVolatile; +} + +bool PurgeableBuffer::wasPurged() const +{ + if (m_state == NonVolatile) + return false; + if (m_state == Purged) + return true; + + int state; + kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_GET_STATE, &state); + + if (ret != KERN_SUCCESS) { + // If that failed we have no clue what state we are in so assume purged. + m_state = Purged; + return true; + } + + if (state & VM_PURGABLE_EMPTY) { + m_state = Purged; + return true; + } + + return false; +} + +const char* PurgeableBuffer::data() const +{ + ASSERT(m_state == NonVolatile); + return m_data; +} + +} + +#endif // BUILDING_ON_TIGER diff --git a/Source/WebCore/platform/mac/RuntimeApplicationChecks.h b/Source/WebCore/platform/mac/RuntimeApplicationChecks.h new file mode 100644 index 0000000..f938048 --- /dev/null +++ b/Source/WebCore/platform/mac/RuntimeApplicationChecks.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 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 AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RuntimeApplicationChecks_h +#define RuntimeApplicationChecks_h + +namespace WebCore { + +bool applicationIsAppleMail(); +bool applicationIsSafari(); +bool applicationIsMicrosoftMessenger(); +bool applicationIsAdobeInstaller(); +bool applicationIsAOLInstantMessenger(); +bool applicationIsMicrosoftMyDay(); + +} // namespace WebCore + +#endif // RuntimeApplicationChecks_h diff --git a/Source/WebCore/platform/mac/RuntimeApplicationChecks.mm b/Source/WebCore/platform/mac/RuntimeApplicationChecks.mm new file mode 100644 index 0000000..7fe8378 --- /dev/null +++ b/Source/WebCore/platform/mac/RuntimeApplicationChecks.mm @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009 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 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. + */ + +#import "config.h" +#import "RuntimeApplicationChecks.h" + + +namespace WebCore { + +bool applicationIsAppleMail() +{ + static const bool isAppleMail = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.mail"]; + return isAppleMail; +} + +bool applicationIsSafari() +{ + static const bool isSafari = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"]; + return isSafari; +} + +bool applicationIsMicrosoftMessenger() +{ + static bool isMicrosoftMessenger = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.microsoft.Messenger"]; + return isMicrosoftMessenger; +} + +bool applicationIsAdobeInstaller() +{ + static bool isAdobeInstaller = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.adobe.Installers.Setup"]; + return isAdobeInstaller; +} + +bool applicationIsAOLInstantMessenger() +{ + static bool isAOLInstantMessenger = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.aol.aim.desktop"]; + return isAOLInstantMessenger; +} + +bool applicationIsMicrosoftMyDay() +{ + static bool isMicrosoftMyDay = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.microsoft.myday"]; + return isMicrosoftMyDay; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/SSLKeyGeneratorMac.mm b/Source/WebCore/platform/mac/SSLKeyGeneratorMac.mm new file mode 100644 index 0000000..dd76b59 --- /dev/null +++ b/Source/WebCore/platform/mac/SSLKeyGeneratorMac.mm @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2003, 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. + */ + +#import "config.h" +#import "SSLKeyGenerator.h" + +#import "KURL.h" +#import "WebCoreKeyGenerator.h" + +namespace WebCore { + +void getSupportedKeySizes(Vector<String>& supportedKeySizes) +{ + NSEnumerator *enumerator = [[[WebCoreKeyGenerator sharedGenerator] strengthMenuItemTitles] objectEnumerator]; + NSString *string; + while ((string = [enumerator nextObject]) != nil) + supportedKeySizes.append(string); +} + +String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const KURL& url) +{ + return [[WebCoreKeyGenerator sharedGenerator] signedPublicKeyAndChallengeStringWithStrengthIndex:keySizeIndex + challenge:challengeString + pageURL:url]; +} + +} diff --git a/Source/WebCore/platform/mac/SchedulePairMac.mm b/Source/WebCore/platform/mac/SchedulePairMac.mm new file mode 100644 index 0000000..e1709b3 --- /dev/null +++ b/Source/WebCore/platform/mac/SchedulePairMac.mm @@ -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. + * 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 "SchedulePair.h" + +namespace WebCore { + +SchedulePair::SchedulePair(NSRunLoop* runLoop, CFStringRef mode) + : m_nsRunLoop(runLoop) + , m_runLoop([runLoop getCFRunLoop]) +{ + if (mode) + m_mode.adoptCF(CFStringCreateCopy(0, mode)); +} + +} // namespace diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.h b/Source/WebCore/platform/mac/ScrollAnimatorMac.h new file mode 100644 index 0000000..234e43c --- /dev/null +++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ScrollAnimatorMac_h +#define ScrollAnimatorMac_h + +#if ENABLE(SMOOTH_SCROLLING) + +#include "FloatPoint.h" +#include "ScrollAnimator.h" +#include <wtf/RetainPtr.h> + +#ifdef __OBJC__ +@class ScrollAnimationHelperDelegate; +#else +class ScrollAnimationHelperDelegate; +#endif + +namespace WebCore { + +class ScrollAnimatorMac : public ScrollAnimator { +public: + ScrollAnimatorMac(ScrollbarClient*); + virtual ~ScrollAnimatorMac(); + + virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier); + virtual void setScrollPositionAndStopAnimation(ScrollbarOrientation, float position); + + // Called by the ScrollAnimationHelperDelegate. + FloatPoint currentPosition() const; + void immediateScrollToPoint(const FloatPoint& newPosition); + +private: + RetainPtr<id> m_scrollAnimationHelper; + RetainPtr<ScrollAnimationHelperDelegate> m_scrollAnimationHelperDelegate; +}; + +} // namespace WebCore + +#endif // ENABLE(SMOOTH_SCROLLING) + +#endif // ScrollAnimatorMac_h diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm new file mode 100644 index 0000000..ca71bd3 --- /dev/null +++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(SMOOTH_SCROLLING) + +#include "ScrollAnimatorMac.h" +#include "ScrollbarClient.h" + +@interface NSObject (NSScrollAnimationHelperDetails) +- (id)initWithDelegate:(id)delegate; +- (void)_stopRun; +- (BOOL)_isAnimating; +- (NSPoint)targetOrigin; +@end + +@interface ScrollAnimationHelperDelegate : NSObject +{ + WebCore::ScrollAnimatorMac* _animator; +} + +- (id)initWithScrollAnimator:(WebCore::ScrollAnimatorMac*)scrollAnimator; + +- (NSRect)bounds; +- (void)_immediateScrollToPoint:(NSPoint)newPosition; +- (NSSize)convertSizeToBase:(NSSize)size; +- (NSSize)convertSizeFromBase:(NSSize)size; + +- (id)superview; // Return nil. +- (id)documentView; // Return nil. +- (id)window; // Return nil. +- (void)_recursiveRecomputeToolTips; // No-op. +@end + +static NSSize abs(NSSize size) +{ + NSSize finalSize = size; + if (finalSize.width < 0) + finalSize.width = -finalSize.width; + if (finalSize.height < 0) + finalSize.height = -finalSize.height; + return finalSize; +} + +@implementation ScrollAnimationHelperDelegate + +- (id)initWithScrollAnimator:(WebCore::ScrollAnimatorMac*)scrollAnimator +{ + self = [super init]; + if (!self) + return nil; + + _animator = scrollAnimator; + return self; +} + +- (NSRect)bounds +{ + WebCore::FloatPoint currentPosition = _animator->currentPosition(); + return NSMakeRect(currentPosition.x(), currentPosition.y(), 0, 0); +} + +- (void)_immediateScrollToPoint:(NSPoint)newPosition +{ + _animator->immediateScrollToPoint(newPosition); +} + +- (NSSize)convertSizeToBase:(NSSize)size +{ + return abs(size); +} + +- (NSSize)convertSizeFromBase:(NSSize)size +{ + return abs(size); +} + +- (id)superview +{ + return nil; +} + +- (id)documentView +{ + return nil; +} + +- (id)window +{ + return nil; +} + +- (void)_recursiveRecomputeToolTips +{ +} + +@end + +namespace WebCore { + +ScrollAnimator* ScrollAnimator::create(ScrollbarClient* client) +{ + return new ScrollAnimatorMac(client); +} + +ScrollAnimatorMac::ScrollAnimatorMac(ScrollbarClient* client) + : ScrollAnimator(client) +{ + m_scrollAnimationHelperDelegate.adoptNS([[ScrollAnimationHelperDelegate alloc] initWithScrollAnimator:this]); + m_scrollAnimationHelper.adoptNS([[NSClassFromString(@"NSScrollAnimationHelper") alloc] initWithDelegate:m_scrollAnimationHelperDelegate.get()]); +} + +ScrollAnimatorMac::~ScrollAnimatorMac() +{ +} + +bool ScrollAnimatorMac::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier) +{ + if (![[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollAnimationEnabled"]) + return ScrollAnimator::scroll(orientation, granularity, step, multiplier); + + if (granularity == ScrollByPixel) + return ScrollAnimator::scroll(orientation, granularity, step, multiplier); + + float currentPos = orientation == HorizontalScrollbar ? m_currentPosX : m_currentPosY; + float newPos = std::max<float>(std::min<float>(currentPos + (step * multiplier), static_cast<float>(m_client->scrollSize(orientation))), 0); + if (currentPos == newPos) + return false; + + NSPoint newPoint; + if ([m_scrollAnimationHelper.get() _isAnimating]) { + NSPoint targetOrigin = [m_scrollAnimationHelper.get() targetOrigin]; + newPoint = orientation == HorizontalScrollbar ? NSMakePoint(newPos, targetOrigin.y) : NSMakePoint(targetOrigin.x, newPos); + } else + newPoint = orientation == HorizontalScrollbar ? NSMakePoint(newPos, m_currentPosY) : NSMakePoint(m_currentPosX, newPos); + + [m_scrollAnimationHelper.get() scrollToPoint:newPoint]; + return true; +} + +void ScrollAnimatorMac::setScrollPositionAndStopAnimation(ScrollbarOrientation orientation, float pos) +{ + [m_scrollAnimationHelper.get() _stopRun]; + ScrollAnimator::setScrollPositionAndStopAnimation(orientation, pos); +} + +FloatPoint ScrollAnimatorMac::currentPosition() const +{ + return FloatPoint(m_currentPosX, m_currentPosY); +} + +void ScrollAnimatorMac::immediateScrollToPoint(const FloatPoint& newPosition) +{ + m_currentPosX = newPosition.x(); + m_currentPosY = newPosition.y(); + + m_client->setScrollOffsetFromAnimation(IntPoint(m_currentPosX, m_currentPosY)); +} + +} // namespace WebCore + +#endif // ENABLE(SMOOTH_SCROLLING) diff --git a/Source/WebCore/platform/mac/ScrollViewMac.mm b/Source/WebCore/platform/mac/ScrollViewMac.mm new file mode 100644 index 0000000..93ec971 --- /dev/null +++ b/Source/WebCore/platform/mac/ScrollViewMac.mm @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2004, 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. + */ + +#import "config.h" +#import "ScrollView.h" + +#import "BlockExceptions.h" +#import "FloatRect.h" +#import "IntRect.h" +#import "Logging.h" +#import "NotImplemented.h" +#import "WebCoreFrameView.h" + +using namespace std; + +@interface NSWindow (WebWindowDetails) +- (BOOL)_needsToResetDragMargins; +- (void)_setNeedsToResetDragMargins:(BOOL)needs; +@end + +namespace WebCore { + +inline NSScrollView<WebCoreFrameScrollView> *ScrollView::scrollView() const +{ + ASSERT(!platformWidget() || [platformWidget() isKindOfClass:[NSScrollView class]]); + ASSERT(!platformWidget() || [platformWidget() conformsToProtocol:@protocol(WebCoreFrameScrollView)]); + return static_cast<NSScrollView<WebCoreFrameScrollView> *>(platformWidget()); +} + +NSView *ScrollView::documentView() const +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [scrollView() documentView]; + END_BLOCK_OBJC_EXCEPTIONS; + return nil; +} + +void ScrollView::platformAddChild(Widget* child) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSView *parentView = documentView(); + NSView *childView = child->getOuterView(); + ASSERT(![parentView isDescendantOf:childView]); + + // Suppress the resetting of drag margins since we know we can't affect them. + NSWindow *window = [parentView window]; + BOOL resetDragMargins = [window _needsToResetDragMargins]; + [window _setNeedsToResetDragMargins:NO]; + if ([childView superview] != parentView) + [parentView addSubview:childView]; + [window _setNeedsToResetDragMargins:resetDragMargins]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +void ScrollView::platformRemoveChild(Widget* child) +{ + child->removeFromSuperview(); +} + +void ScrollView::platformSetScrollbarModes() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [scrollView() setScrollingModes:m_horizontalScrollbarMode vertical:m_verticalScrollbarMode andLock:NO]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [scrollView() scrollingModes:&horizontal vertical:&vertical]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +void ScrollView::platformSetCanBlitOnScroll(bool canBlitOnScroll) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +bool ScrollView::platformCanBlitOnScroll() const +{ + return [[scrollView() contentView] copiesOnScroll]; +} + +IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + IntRect result = enclosingIntRect([scrollView() documentVisibleRect]); + if (includeScrollbars) + result.setSize(IntSize([scrollView() frame].size)); + return result; + END_BLOCK_OBJC_EXCEPTIONS; + return IntRect(); +} + +IntSize ScrollView::platformContentsSize() const +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + if (NSView* documentView = this->documentView()) + return enclosingIntRect([documentView bounds]).size(); + END_BLOCK_OBJC_EXCEPTIONS; + return IntSize(); +} + +void ScrollView::platformSetContentsSize() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + int w = m_contentsSize.width(); + int h = m_contentsSize.height(); + LOG(Frames, "%p %@ at w %d h %d\n", documentView(), [(id)[documentView() class] className], w, h); + NSSize tempSize = { max(0, w), max(0, h) }; // workaround for 4213314 + [documentView() setFrameSize:tempSize]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [scrollView() setScrollBarsSuppressed:m_scrollbarsSuppressed + repaintOnUnsuppress:repaintOnUnsuppress]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSPoint floatPoint = scrollPoint; + NSPoint tempPoint = { max(-[scrollView() scrollOrigin].x, floatPoint.x), max(-[scrollView() scrollOrigin].y, floatPoint.y) }; // Don't use NSMakePoint to work around 4213314. + [documentView() scrollPoint:tempPoint]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity) +{ + // FIXME: It would be nice to implement this so that all of the code in WebFrameView could go away. + notImplemented(); + return false; +} + +void ScrollView::platformRepaintContentRectangle(const IntRect& rect, bool now) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSView *view = documentView(); + [view setNeedsDisplayInRect:rect]; + if (now) { + [[view window] displayIfNeeded]; + [[view window] flushWindowIfNeeded]; + } + END_BLOCK_OBJC_EXCEPTIONS; +} + +// "Containing Window" means the NSWindow's coord system, which is origin lower left + +IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + if (NSView* documentView = this->documentView()) { + NSRect tempRect = rect; + tempRect = [documentView convertRect:tempRect toView:nil]; + tempRect.origin = [[documentView window] convertBaseToScreen:tempRect.origin]; + return enclosingIntRect(tempRect); + } + END_BLOCK_OBJC_EXCEPTIONS; + return IntRect(); +} + +IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + if (NSView* documentView = this->documentView()) { + NSPoint windowCoord = [[documentView window] convertScreenToBase: point]; + return IntPoint([documentView convertPoint:windowCoord fromView:nil]); + } + END_BLOCK_OBJC_EXCEPTIONS; + return IntPoint(); +} + +bool ScrollView::platformIsOffscreen() const +{ + return ![platformWidget() window] || ![[platformWidget() window] isVisible]; +} + +void ScrollView::platformSetScrollOrigin(const IntPoint& origin, bool updatePosition) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [scrollView() setScrollOrigin:origin updatePosition:updatePosition]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/ScrollbarThemeMac.h b/Source/WebCore/platform/mac/ScrollbarThemeMac.h new file mode 100644 index 0000000..c833ee7 --- /dev/null +++ b/Source/WebCore/platform/mac/ScrollbarThemeMac.h @@ -0,0 +1,72 @@ +/* + * 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 ScrollbarThemeMac_h +#define ScrollbarThemeMac_h + +#include "ScrollbarThemeComposite.h" + +namespace WebCore { + +class ScrollbarThemeMac : public ScrollbarThemeComposite { +public: + ScrollbarThemeMac(); + virtual ~ScrollbarThemeMac(); + + virtual bool paint(Scrollbar*, GraphicsContext* context, const IntRect& damageRect); + + virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + + virtual bool supportsControlTints() const { return true; } + + virtual double initialAutoscrollTimerDelay(); + virtual double autoscrollTimerDelay(); + + virtual ScrollbarButtonsPlacement buttonsPlacement() const; + + virtual void registerScrollbar(Scrollbar*); + virtual void unregisterScrollbar(Scrollbar*); + +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 maxOverlapBetweenPages() { return 40; } + + virtual int minimumThumbLength(Scrollbar*); + + virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&); + +public: + void preferencesChanged(); +}; + +} + +#endif diff --git a/Source/WebCore/platform/mac/ScrollbarThemeMac.mm b/Source/WebCore/platform/mac/ScrollbarThemeMac.mm new file mode 100644 index 0000000..ce3be1a --- /dev/null +++ b/Source/WebCore/platform/mac/ScrollbarThemeMac.mm @@ -0,0 +1,405 @@ +/* + * 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 "ScrollbarThemeMac.h" + +#include "ImageBuffer.h" +#include "PlatformMouseEvent.h" +#include "ScrollView.h" +#include <Carbon/Carbon.h> +#include <wtf/StdLibExtras.h> +#include <wtf/UnusedParam.h> + +// FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow. + +using namespace std; +using namespace WebCore; + +static HashSet<Scrollbar*>* gScrollbars; + +@interface ScrollbarPrefsObserver : NSObject +{ + +} + ++ (void)registerAsObserver; ++ (void)appearancePrefsChanged:(NSNotification*)theNotification; ++ (void)behaviorPrefsChanged:(NSNotification*)theNotification; + +@end + +@implementation ScrollbarPrefsObserver + ++ (void)appearancePrefsChanged:(NSNotification*)unusedNotification +{ + UNUSED_PARAM(unusedNotification); + + static_cast<ScrollbarThemeMac*>(ScrollbarTheme::nativeTheme())->preferencesChanged(); + if (!gScrollbars) + return; + HashSet<Scrollbar*>::iterator end = gScrollbars->end(); + for (HashSet<Scrollbar*>::iterator it = gScrollbars->begin(); it != end; ++it) { + (*it)->styleChanged(); + (*it)->invalidate(); + } +} + ++ (void)behaviorPrefsChanged:(NSNotification*)unusedNotification +{ + UNUSED_PARAM(unusedNotification); + + static_cast<ScrollbarThemeMac*>(ScrollbarTheme::nativeTheme())->preferencesChanged(); +} + ++ (void)registerAsObserver +{ + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(appearancePrefsChanged:) name:@"AppleAquaScrollBarVariantChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(behaviorPrefsChanged:) name:@"AppleNoRedisplayAppearancePreferenceChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce]; +} + +@end + +namespace WebCore { + +ScrollbarTheme* ScrollbarTheme::nativeTheme() +{ + DEFINE_STATIC_LOCAL(ScrollbarThemeMac, theme, ()); + return &theme; +} + +// 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 }; + +static int cOuterButtonLength[] = { 16, 14 }; // The outer button in a double button pair is a bit bigger. +static int cOuterButtonOverlap = 2; + +static float gInitialButtonDelay = 0.5f; +static float gAutoscrollButtonDelay = 0.05f; +static bool gJumpOnTrackClick = false; +static ScrollbarButtonsPlacement gButtonPlacement = ScrollbarButtonsDoubleEnd; + +static void updateArrowPlacement() +{ + NSString *buttonPlacement = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleScrollBarVariant"]; + if ([buttonPlacement isEqualToString:@"Single"]) + gButtonPlacement = ScrollbarButtonsSingle; + else if ([buttonPlacement isEqualToString:@"DoubleMin"]) + gButtonPlacement = ScrollbarButtonsDoubleStart; + else if ([buttonPlacement isEqualToString:@"DoubleBoth"]) + gButtonPlacement = ScrollbarButtonsDoubleBoth; + else + gButtonPlacement = ScrollbarButtonsDoubleEnd; // The default is ScrollbarButtonsDoubleEnd. +} + +void ScrollbarThemeMac::registerScrollbar(Scrollbar* scrollbar) +{ + if (!gScrollbars) + gScrollbars = new HashSet<Scrollbar*>; + gScrollbars->add(scrollbar); +} + +void ScrollbarThemeMac::unregisterScrollbar(Scrollbar* scrollbar) +{ + gScrollbars->remove(scrollbar); + if (gScrollbars->isEmpty()) { + delete gScrollbars; + gScrollbars = 0; + } +} + +ScrollbarThemeMac::ScrollbarThemeMac() +{ + static bool initialized; + if (!initialized) { + initialized = true; + [ScrollbarPrefsObserver registerAsObserver]; + preferencesChanged(); + } +} + +ScrollbarThemeMac::~ScrollbarThemeMac() +{ +} + +void ScrollbarThemeMac::preferencesChanged() +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults synchronize]; + updateArrowPlacement(); + gInitialButtonDelay = [defaults floatForKey:@"NSScrollerButtonDelay"]; + gAutoscrollButtonDelay = [defaults floatForKey:@"NSScrollerButtonPeriod"]; + gJumpOnTrackClick = [defaults boolForKey:@"AppleScrollerPagingBehavior"]; +} + +int ScrollbarThemeMac::scrollbarThickness(ScrollbarControlSize controlSize) +{ + return cScrollbarThickness[controlSize]; +} + +double ScrollbarThemeMac::initialAutoscrollTimerDelay() +{ + return gInitialButtonDelay; +} + +double ScrollbarThemeMac::autoscrollTimerDelay() +{ + return gAutoscrollButtonDelay; +} + +ScrollbarButtonsPlacement ScrollbarThemeMac::buttonsPlacement() const +{ + return gButtonPlacement; +} + +bool ScrollbarThemeMac::hasButtons(Scrollbar* scrollbar) +{ + return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? + scrollbar->width() : + scrollbar->height()) >= 2 * (cRealButtonLength[scrollbar->controlSize()] - cButtonHitInset[scrollbar->controlSize()]); +} + +bool ScrollbarThemeMac::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 ScrollbarThemeMac::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) +{ + IntRect result; + + if (part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd)) + return result; + + if (part == BackButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsSingle)) + return result; + + int thickness = scrollbarThickness(scrollbar->controlSize()); + bool outerButton = part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsDoubleBoth); + if (outerButton) { + if (scrollbar->orientation() == HorizontalScrollbar) + result = IntRect(scrollbar->x(), scrollbar->y(), cOuterButtonLength[scrollbar->controlSize()] + painting ? cOuterButtonOverlap : 0, thickness); + else + result = IntRect(scrollbar->x(), scrollbar->y(), thickness, cOuterButtonLength[scrollbar->controlSize()] + painting ? cOuterButtonOverlap : 0); + return result; + } + + // Our repaint rect is slightly larger, since we are a button that is adjacent to the track. + if (scrollbar->orientation() == HorizontalScrollbar) { + int start = part == BackButtonStartPart ? scrollbar->x() : scrollbar->x() + scrollbar->width() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()]; + result = IntRect(start, scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness); + } else { + int start = part == BackButtonStartPart ? scrollbar->y() : scrollbar->y() + scrollbar->height() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()]; + result = IntRect(scrollbar->x(), start, thickness, cButtonLength[scrollbar->controlSize()]); + } + + if (painting) + return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == BackButtonStartPart); + return result; +} + +IntRect ScrollbarThemeMac::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) +{ + IntRect result; + + if (part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart)) + return result; + + if (part == ForwardButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsSingle)) + return result; + + int thickness = scrollbarThickness(scrollbar->controlSize()); + int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()]; + int buttonLength = cButtonLength[scrollbar->controlSize()]; + + bool outerButton = part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsDoubleBoth); + if (outerButton) { + if (scrollbar->orientation() == HorizontalScrollbar) { + result = IntRect(scrollbar->x() + scrollbar->width() - outerButtonLength, scrollbar->y(), outerButtonLength, thickness); + if (painting) + result.inflateX(cOuterButtonOverlap); + } else { + result = IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - outerButtonLength, thickness, outerButtonLength); + if (painting) + result.inflateY(cOuterButtonOverlap); + } + return result; + } + + if (scrollbar->orientation() == HorizontalScrollbar) { + int start = part == ForwardButtonEndPart ? scrollbar->x() + scrollbar->width() - buttonLength : scrollbar->x() + outerButtonLength; + result = IntRect(start, scrollbar->y(), buttonLength, thickness); + } else { + int start = part == ForwardButtonEndPart ? scrollbar->y() + scrollbar->height() - buttonLength : scrollbar->y() + outerButtonLength; + result = IntRect(scrollbar->x(), start, thickness, buttonLength); + } + if (painting) + return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == ForwardButtonStartPart); + return result; +} + +IntRect ScrollbarThemeMac::trackRect(Scrollbar* scrollbar, bool painting) +{ + if (painting || !hasButtons(scrollbar)) + return scrollbar->frameRect(); + + IntRect result; + int thickness = scrollbarThickness(scrollbar->controlSize()); + int startWidth = 0; + int endWidth = 0; + int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()]; + int buttonLength = cButtonLength[scrollbar->controlSize()]; + int doubleButtonLength = outerButtonLength + buttonLength; + switch (buttonsPlacement()) { + case ScrollbarButtonsSingle: + startWidth = buttonLength; + endWidth = buttonLength; + break; + case ScrollbarButtonsDoubleStart: + startWidth = doubleButtonLength; + break; + case ScrollbarButtonsDoubleEnd: + endWidth = doubleButtonLength; + break; + case ScrollbarButtonsDoubleBoth: + startWidth = doubleButtonLength; + endWidth = doubleButtonLength; + break; + default: + break; + } + + int totalWidth = startWidth + endWidth; + if (scrollbar->orientation() == HorizontalScrollbar) + return IntRect(scrollbar->x() + startWidth, scrollbar->y(), scrollbar->width() - totalWidth, thickness); + return IntRect(scrollbar->x(), scrollbar->y() + startWidth, thickness, scrollbar->height() - totalWidth); +} + +int ScrollbarThemeMac::minimumThumbLength(Scrollbar* scrollbar) +{ + return cThumbMinLength[scrollbar->controlSize()]; +} + +bool ScrollbarThemeMac::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt) +{ + if (evt.button() != LeftButton) + return false; + if (gJumpOnTrackClick) + return !evt.altKey(); + return evt.altKey(); +} + +static int scrollbarPartToHIPressedState(ScrollbarPart part) +{ + switch (part) { + case BackButtonStartPart: + return kThemeTopOutsideArrowPressed; + case BackButtonEndPart: + return kThemeTopOutsideArrowPressed; // This does not make much sense. For some reason the outside constant is required. + case ForwardButtonStartPart: + return kThemeTopInsideArrowPressed; + case ForwardButtonEndPart: + return kThemeBottomOutsideArrowPressed; + case ThumbPart: + return kThemeThumbPressed; + default: + return 0; + } +} + +bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& damageRect) +{ + HIThemeTrackDrawInfo trackInfo; + trackInfo.version = 0; + trackInfo.kind = scrollbar->controlSize() == RegularScrollbar ? kThemeMediumScrollBar : kThemeSmallScrollBar; + trackInfo.bounds = scrollbar->frameRect(); + trackInfo.min = 0; + trackInfo.max = scrollbar->maximum(); + trackInfo.value = scrollbar->currentPos(); + trackInfo.trackInfo.scrollbar.viewsize = scrollbar->visibleSize(); + trackInfo.attributes = 0; + if (scrollbar->orientation() == HorizontalScrollbar) + trackInfo.attributes |= kThemeTrackHorizontal; + + if (!scrollbar->enabled()) + trackInfo.enableState = kThemeTrackDisabled; + else + trackInfo.enableState = scrollbar->client()->isActive() ? kThemeTrackActive : kThemeTrackInactive; + + if (hasThumb(scrollbar)) + trackInfo.attributes |= kThemeTrackShowThumb; + else if (!hasButtons(scrollbar)) + trackInfo.enableState = kThemeTrackNothingToScroll; + trackInfo.trackInfo.scrollbar.pressState = scrollbarPartToHIPressedState(scrollbar->pressedPart()); + + // The Aqua scrollbar is buggy when rotated and scaled. We will just draw into a bitmap if we detect a scale or rotation. + const AffineTransform& currentCTM = context->getCTM(); + bool canDrawDirectly = currentCTM.isIdentityOrTranslationOrFlipped(); + if (canDrawDirectly) + HIThemeDrawTrack(&trackInfo, 0, context->platformContext(), kHIThemeOrientationNormal); + else { + trackInfo.bounds = IntRect(IntPoint(), scrollbar->frameRect().size()); + + IntRect bufferRect(scrollbar->frameRect()); + bufferRect.intersect(damageRect); + bufferRect.move(-scrollbar->frameRect().x(), -scrollbar->frameRect().y()); + + OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(bufferRect.size()); + if (!imageBuffer) + return true; + + HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal); + context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, scrollbar->frameRect().location()); + } + + return true; +} + +} + diff --git a/Source/WebCore/platform/mac/SearchPopupMenuMac.h b/Source/WebCore/platform/mac/SearchPopupMenuMac.h new file mode 100644 index 0000000..828b07f --- /dev/null +++ b/Source/WebCore/platform/mac/SearchPopupMenuMac.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef SearchPopupMenuMac_h +#define SearchPopupMenuMac_h + +#include "PopupMenuMac.h" +#include "SearchPopupMenu.h" + +namespace WebCore { + +class SearchPopupMenuMac : public SearchPopupMenu { +public: + SearchPopupMenuMac(PopupMenuClient*); + + virtual PopupMenu* popupMenu(); + virtual void saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems); + virtual void loadRecentSearches(const AtomicString& name, Vector<String>& searchItems); + virtual bool enabled(); + +private: + RefPtr<PopupMenuMac> m_popup; +}; + +} + +#endif // SearchPopupMenuMac_h diff --git a/Source/WebCore/platform/mac/SearchPopupMenuMac.mm b/Source/WebCore/platform/mac/SearchPopupMenuMac.mm new file mode 100644 index 0000000..47d6e57 --- /dev/null +++ b/Source/WebCore/platform/mac/SearchPopupMenuMac.mm @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#import "config.h" +#import "SearchPopupMenuMac.h" + +#include <wtf/text/AtomicString.h> + +namespace WebCore { + +SearchPopupMenuMac::SearchPopupMenuMac(PopupMenuClient* client) + : m_popup(adoptRef(new PopupMenuMac(client))) +{ +} + +static NSString* autosaveKey(const String& name) +{ + return [@"com.apple.WebKit.searchField:" stringByAppendingString:name]; +} + +PopupMenu* SearchPopupMenuMac::popupMenu() +{ + return m_popup.get(); +} + +bool SearchPopupMenuMac::enabled() +{ + return true; +} + +void SearchPopupMenuMac::saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems) +{ + if (name.isEmpty()) + return; + + size_t size = searchItems.size(); + if (size == 0) + [[NSUserDefaults standardUserDefaults] removeObjectForKey:autosaveKey(name)]; + else { + NSMutableArray* items = [[NSMutableArray alloc] initWithCapacity:size]; + for (size_t i = 0; i < size; ++i) + [items addObject:searchItems[i]]; + [[NSUserDefaults standardUserDefaults] setObject:items forKey:autosaveKey(name)]; + [items release]; + } +} + +void SearchPopupMenuMac::loadRecentSearches(const AtomicString& name, Vector<String>& searchItems) +{ + if (name.isEmpty()) + return; + + searchItems.clear(); + NSArray* items = [[NSUserDefaults standardUserDefaults] arrayForKey:autosaveKey(name)]; + size_t size = [items count]; + for (size_t i = 0; i < size; ++i) { + NSString* item = [items objectAtIndex:i]; + if ([item isKindOfClass:[NSString class]]) + searchItems.append(item); + } +} + +} diff --git a/Source/WebCore/platform/mac/SharedBufferMac.mm b/Source/WebCore/platform/mac/SharedBufferMac.mm new file mode 100644 index 0000000..3f5e5d4 --- /dev/null +++ b/Source/WebCore/platform/mac/SharedBufferMac.mm @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2006 Apple Computer, 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 "SharedBuffer.h" + +#include "WebCoreObjCExtras.h" +#include <runtime/InitializeThreading.h> +#include <string.h> +#include <wtf/PassRefPtr.h> + +#ifdef BUILDING_ON_TIGER +typedef unsigned NSUInteger; +#endif + +using namespace WebCore; + +@interface WebCoreSharedBufferData : NSData +{ + RefPtr<SharedBuffer> sharedBuffer; +} + +- (id)initWithSharedBuffer:(SharedBuffer*)buffer; +@end + +@implementation WebCoreSharedBufferData + ++ (void)initialize +{ + JSC::initializeThreading(); + WTF::initializeMainThreadToProcessMainThread(); +#ifndef BUILDING_ON_TIGER + WebCoreObjCFinalizeOnMainThread(self); +#endif +} + +- (void)dealloc +{ + if (WebCoreObjCScheduleDeallocateOnMainThread([WebCoreSharedBufferData class], self)) + return; + + [super dealloc]; +} + +- (void)finalize +{ + [super finalize]; +} + +- (id)initWithSharedBuffer:(SharedBuffer*)buffer +{ + self = [super init]; + + if (self) + sharedBuffer = buffer; + + return self; +} + +- (NSUInteger)length +{ + return sharedBuffer->size(); +} + +- (const void *)bytes +{ + return reinterpret_cast<const void*>(sharedBuffer->data()); +} + +@end + +namespace WebCore { + +PassRefPtr<SharedBuffer> SharedBuffer::wrapNSData(NSData *nsData) +{ + return adoptRef(new SharedBuffer((CFDataRef)nsData)); +} + +NSData *SharedBuffer::createNSData() +{ + return [[WebCoreSharedBufferData alloc] initWithSharedBuffer:this]; +} + +CFDataRef SharedBuffer::createCFData() +{ + if (m_cfData) { + CFRetain(m_cfData.get()); + return m_cfData.get(); + } + + return (CFDataRef)RetainPtr<WebCoreSharedBufferData>(AdoptNS, [[WebCoreSharedBufferData alloc] initWithSharedBuffer:this]).releaseRef(); +} + +PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath) +{ + NSData *resourceData = [NSData dataWithContentsOfFile:filePath]; + if (resourceData) + return SharedBuffer::wrapNSData(resourceData); + return 0; +} + +} + diff --git a/Source/WebCore/platform/mac/SharedTimerMac.mm b/Source/WebCore/platform/mac/SharedTimerMac.mm new file mode 100644 index 0000000..cc9ff17 --- /dev/null +++ b/Source/WebCore/platform/mac/SharedTimerMac.mm @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "SharedTimer.h" + +#import <IOKit/IOMessage.h> +#import <IOKit/pwr_mgt/IOPMLib.h> +#import <wtf/Assertions.h> +#import <wtf/Noncopyable.h> +#import <wtf/PassOwnPtr.h> +#import <wtf/UnusedParam.h> + +#include <stdio.h> + +// On Snow Leopard and newer we'll ask IOKit to deliver notifications on a queue. +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) +#define IOKIT_WITHOUT_LIBDISPATCH 1 +#endif + +namespace WebCore { + +static CFRunLoopTimerRef sharedTimer; +static void (*sharedTimerFiredFunction)(); +static void timerFired(CFRunLoopTimerRef, void*); + +#if !defined(IOKIT_WITHOUT_LIBDISPATCH) && defined(BUILDING_ON_SNOW_LEOPARD) +extern "C" void IONotificationPortSetDispatchQueue(IONotificationPortRef notify, dispatch_queue_t queue); +#endif + +class PowerObserver { + WTF_MAKE_NONCOPYABLE(PowerObserver); + +public: + static PassOwnPtr<PowerObserver> create() + { + return adoptPtr(new PowerObserver); + } + ~PowerObserver(); + +private: + PowerObserver(); + + static void didReceiveSystemPowerNotification(void* context, io_service_t, uint32_t messageType, void* messageArgument); + void didReceiveSystemPowerNotification(io_service_t, uint32_t messageType, void* messageArgument); + + void restartSharedTimer(); + + io_connect_t m_powerConnection; + IONotificationPortRef m_notificationPort; + io_object_t m_notifierReference; +#ifdef IOKIT_WITHOUT_LIBDISPATCH + CFRunLoopSourceRef m_runLoopSource; +#else + dispatch_queue_t m_dispatchQueue; +#endif +}; + +PowerObserver::PowerObserver() + : m_powerConnection(0) + , m_notificationPort(0) + , m_notifierReference(0) +#ifdef IOKIT_WITHOUT_LIBDISPATCH + , m_runLoopSource(0) +#else + , m_dispatchQueue(dispatch_queue_create("com.apple.WebKit.PowerObserver", 0)) +#endif +{ + m_powerConnection = IORegisterForSystemPower(this, &m_notificationPort, didReceiveSystemPowerNotification, &m_notifierReference); + if (!m_powerConnection) + return; + +#ifdef IOKIT_WITHOUT_LIBDISPATCH + m_runLoopSource = IONotificationPortGetRunLoopSource(m_notificationPort); + CFRunLoopAddSource(CFRunLoopGetMain(), m_runLoopSource, kCFRunLoopCommonModes); +#else + IONotificationPortSetDispatchQueue(m_notificationPort, m_dispatchQueue); +#endif +} + +PowerObserver::~PowerObserver() +{ + if (!m_powerConnection) + return; + +#ifdef IOKIT_WITHOUT_LIBDISPATCH + CFRunLoopRemoveSource(CFRunLoopGetMain(), m_runLoopSource, kCFRunLoopCommonModes); +#else + dispatch_release(m_dispatchQueue); +#endif + + IODeregisterForSystemPower(&m_notifierReference); + IOServiceClose(m_powerConnection); + IONotificationPortDestroy(m_notificationPort); +} + +void PowerObserver::didReceiveSystemPowerNotification(void* context, io_service_t service, uint32_t messageType, void* messageArgument) +{ + static_cast<PowerObserver*>(context)->didReceiveSystemPowerNotification(service, messageType, messageArgument); +} + +void PowerObserver::didReceiveSystemPowerNotification(io_service_t, uint32_t messageType, void* messageArgument) +{ + IOAllowPowerChange(m_powerConnection, reinterpret_cast<long>(messageArgument)); + + // We only care about the "wake from sleep" message. + if (messageType != kIOMessageSystemWillPowerOn) + return; + +#ifdef IOKIT_WITHOUT_LIBDISPATCH + restartSharedTimer(); +#else + // We need to restart the timer on the main thread. + CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, ^() { + restartSharedTimer(); + }); +#endif +} + +void PowerObserver::restartSharedTimer() +{ + ASSERT(CFRunLoopGetCurrent() == CFRunLoopGetMain()); + + if (!sharedTimer) + return; + + stopSharedTimer(); + timerFired(0, 0); +} + +static PowerObserver* PowerObserver; + +void setSharedTimerFiredFunction(void (*f)()) +{ + ASSERT(!sharedTimerFiredFunction || sharedTimerFiredFunction == f); + + sharedTimerFiredFunction = f; +} + +static void timerFired(CFRunLoopTimerRef, void*) +{ + // FIXME: We can remove this global catch-all if we fix <rdar://problem/5299018>. + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + sharedTimerFiredFunction(); + [pool drain]; +} + +void setSharedTimerFireTime(double fireTime) +{ + ASSERT(sharedTimerFiredFunction); + + if (sharedTimer) { + CFRunLoopTimerInvalidate(sharedTimer); + CFRelease(sharedTimer); + } + + CFAbsoluteTime fireDate = fireTime - kCFAbsoluteTimeIntervalSince1970; + sharedTimer = CFRunLoopTimerCreate(0, fireDate, 0, 0, 0, timerFired, 0); + CFRunLoopAddTimer(CFRunLoopGetCurrent(), sharedTimer, kCFRunLoopCommonModes); + + if (!PowerObserver) + PowerObserver = PowerObserver::create().leakPtr(); +} + +void stopSharedTimer() +{ + if (sharedTimer) { + CFRunLoopTimerInvalidate(sharedTimer); + CFRelease(sharedTimer); + sharedTimer = 0; + } +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/SoftLinking.h b/Source/WebCore/platform/mac/SoftLinking.h new file mode 100644 index 0000000..ce72f34 --- /dev/null +++ b/Source/WebCore/platform/mac/SoftLinking.h @@ -0,0 +1,119 @@ +/* + * 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. + */ + +#import <wtf/Assertions.h> +#import <dlfcn.h> + +#define SOFT_LINK_LIBRARY(lib) \ + static void* lib##Library() \ + { \ + static void* dylib = dlopen("/usr/lib/" #lib ".dylib", RTLD_NOW); \ + ASSERT(dylib); \ + return dylib; \ + } + +#define SOFT_LINK_FRAMEWORK(framework) \ + static void* framework##Library() \ + { \ + static void* frameworkLibrary = dlopen("/System/Library/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \ + ASSERT(frameworkLibrary); \ + return frameworkLibrary; \ + } + +#define SOFT_LINK(framework, functionName, resultType, parameterDeclarations, parameterNames) \ + static resultType init##functionName parameterDeclarations; \ + static resultType (*softLink##functionName) parameterDeclarations = init##functionName; \ + \ + static resultType init##functionName parameterDeclarations \ + { \ + softLink##functionName = (resultType (*) parameterDeclarations) dlsym(framework##Library(), #functionName); \ + ASSERT(softLink##functionName); \ + return softLink##functionName parameterNames; \ + }\ + \ + inline resultType functionName parameterDeclarations \ + {\ + return softLink##functionName parameterNames; \ + } + +#define SOFT_LINK_CLASS(framework, className) \ + static Class init##className(); \ + static Class (*get##className##Class)() = init##className; \ + static Class class##className; \ + \ + static Class className##Function() \ + { \ + return class##className; \ + }\ + \ + static Class init##className() \ + { \ + framework##Library(); \ + class##className = objc_getClass(#className); \ + ASSERT(class##className); \ + get##className##Class = className##Function; \ + return class##className; \ + } + +#define SOFT_LINK_POINTER(framework, name, type) \ + static type init##name(); \ + static type (*get##name)() = init##name; \ + static type pointer##name; \ + \ + static type name##Function() \ + { \ + return pointer##name; \ + }\ + \ + static type init##name() \ + { \ + void** pointer = static_cast<void**>(dlsym(framework##Library(), #name)); \ + ASSERT(pointer); \ + pointer##name = static_cast<type>(*pointer); \ + get##name = name##Function; \ + return pointer##name; \ + } + +#define SOFT_LINK_CONSTANT(framework, name, type) \ + static type init##name(); \ + static type (*get##name)() = init##name; \ + static type constant##name; \ + \ + static type name##Function() \ + { \ + return constant##name; \ + }\ + \ + static type init##name() \ + { \ + void* constant = dlsym(framework##Library(), #name); \ + ASSERT(constant); \ + constant##name = *static_cast<type*>(constant); \ + get##name = name##Function; \ + return constant##name; \ + } diff --git a/Source/WebCore/platform/mac/SoundMac.mm b/Source/WebCore/platform/mac/SoundMac.mm new file mode 100644 index 0000000..ced14b8 --- /dev/null +++ b/Source/WebCore/platform/mac/SoundMac.mm @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2006 Apple Computer, 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. + */ + +#import "config.h" +#import "Sound.h" + +namespace WebCore { + +void systemBeep() { NSBeep(); } + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/SuddenTermination.mm b/Source/WebCore/platform/mac/SuddenTermination.mm new file mode 100644 index 0000000..513d01b --- /dev/null +++ b/Source/WebCore/platform/mac/SuddenTermination.mm @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 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. + */ + +#import "config.h" +#import "SuddenTermination.h" + +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + +namespace WebCore { + +void disableSuddenTermination() +{ + [[NSProcessInfo processInfo] disableSuddenTermination]; +} + +void enableSuddenTermination() +{ + [[NSProcessInfo processInfo] enableSuddenTermination]; +} + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/platform/mac/SystemTimeMac.cpp b/Source/WebCore/platform/mac/SystemTimeMac.cpp new file mode 100644 index 0000000..1b2aae0 --- /dev/null +++ b/Source/WebCore/platform/mac/SystemTimeMac.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006 Apple Computer, 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 "SystemTime.h" + +#include <CoreGraphics/CGEventSource.h> +#include <CoreFoundation/CFDate.h> + +namespace WebCore { + +float userIdleTime() +{ + return static_cast<float>(CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType)); +} + +} diff --git a/Source/WebCore/platform/mac/ThemeMac.h b/Source/WebCore/platform/mac/ThemeMac.h new file mode 100644 index 0000000..bf2d691 --- /dev/null +++ b/Source/WebCore/platform/mac/ThemeMac.h @@ -0,0 +1,59 @@ +/* + * 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 ThemeMac_h +#define ThemeMac_h + +#include "Theme.h" + +namespace WebCore { + +class ThemeMac : public Theme { +public: + ThemeMac() { } + virtual ~ThemeMac() { } + + virtual int baselinePositionAdjustment(ControlPart) const; + + virtual FontDescription controlFont(ControlPart, const Font&, float zoomFactor) const; + + virtual LengthSize controlSize(ControlPart, const Font&, const LengthSize&, float zoomFactor) const; + virtual LengthSize minimumControlSize(ControlPart, const Font&, float zoomFactor) const; + + virtual LengthBox controlPadding(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const; + virtual LengthBox controlBorder(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const; + + virtual bool controlRequiresPreWhiteSpace(ControlPart part) const { return part == PushButtonPart; } + + virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect&, float zoomFactor, ScrollView*) const; + virtual void inflateControlPaintRect(ControlPart, ControlStates, IntRect&, float zoomFactor) const; + + // FIXME: Once RenderThemeMac is converted over to use Theme then this can be internal to ThemeMac. + static NSView* ensuredView(ScrollView*); +}; + +} // namespace WebCore + +#endif // ThemeMac_h diff --git a/Source/WebCore/platform/mac/ThemeMac.mm b/Source/WebCore/platform/mac/ThemeMac.mm new file mode 100644 index 0000000..75cbd36 --- /dev/null +++ b/Source/WebCore/platform/mac/ThemeMac.mm @@ -0,0 +1,738 @@ +/* + * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "ThemeMac.h" + +#import "BlockExceptions.h" +#import "GraphicsContext.h" +#import "LocalCurrentGraphicsContext.h" +#import "ScrollView.h" +#import "WebCoreSystemInterface.h" +#import <Carbon/Carbon.h> +#include <wtf/StdLibExtras.h> + +using namespace std; + +// This is a view whose sole purpose is to tell AppKit that it's flipped. +@interface WebCoreFlippedView : NSView +@end + +@implementation WebCoreFlippedView + +- (BOOL)isFlipped +{ + return YES; +} + +- (NSText *)currentEditor +{ + return nil; +} + +@end + +// FIXME: Default buttons really should be more like push buttons and not like buttons. + +namespace WebCore { + +enum { + topMargin, + rightMargin, + bottomMargin, + leftMargin +}; + +Theme* platformTheme() +{ + DEFINE_STATIC_LOCAL(ThemeMac, themeMac, ()); + return &themeMac; +} + +// Helper functions used by a bunch of different control parts. + +static NSControlSize controlSizeForFont(const Font& font) +{ + int fontSize = font.pixelSize(); + if (fontSize >= 16) + return NSRegularControlSize; + if (fontSize >= 11) + return NSSmallControlSize; + return NSMiniControlSize; +} + +static LengthSize sizeFromNSControlSize(NSControlSize nsControlSize, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes) +{ + IntSize controlSize = sizes[nsControlSize]; + if (zoomFactor != 1.0f) + controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor); + LengthSize result = zoomedSize; + if (zoomedSize.width().isIntrinsicOrAuto() && controlSize.width() > 0) + result.setWidth(Length(controlSize.width(), Fixed)); + if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0) + result.setHeight(Length(controlSize.height(), Fixed)); + return result; +} + +static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes) +{ + return sizeFromNSControlSize(controlSizeForFont(font), zoomedSize, zoomFactor, sizes); +} + +static ControlSize controlSizeFromPixelSize(const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor) +{ + if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomFactor) && + minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomFactor)) + return NSRegularControlSize; + if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) && + minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor)) + return NSSmallControlSize; + return NSMiniControlSize; +} + +static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor) +{ + ControlSize size = controlSizeFromPixelSize(sizes, minZoomedSize, zoomFactor); + if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same. + [cell setControlSize:(NSControlSize)size]; +} + +static void updateStates(NSCell* cell, ControlStates states) +{ + // Hover state is not supported by Aqua. + + // Pressed state + bool oldPressed = [cell isHighlighted]; + bool pressed = states & PressedState; + if (pressed != oldPressed) + [cell setHighlighted:pressed]; + + // Enabled state + bool oldEnabled = [cell isEnabled]; + bool enabled = states & EnabledState; + if (enabled != oldEnabled) + [cell setEnabled:enabled]; + + // Focused state + bool oldFocused = [cell showsFirstResponder]; + bool focused = states & FocusState; + if (focused != oldFocused) + [cell setShowsFirstResponder:focused]; + + // Checked and Indeterminate + bool oldIndeterminate = [cell state] == NSMixedState; + bool indeterminate = (states & IndeterminateState); + bool checked = states & CheckedState; + bool oldChecked = [cell state] == NSOnState; + if (oldIndeterminate != indeterminate || checked != oldChecked) + [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)]; + + // Window inactive state does not need to be checked explicitly, since we paint parented to + // a view in a window whose key state can be detected. +} + +static ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind, ControlStates states) +{ + if (states & ReadOnlyState) + return kThemeStateUnavailableInactive; + if (!(states & EnabledState)) + return kThemeStateUnavailableInactive; + + // Do not process PressedState if !EnabledState or ReadOnlyState. + if (states & PressedState) { + if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kind == kThemeIncDecButtonMini) + return states & SpinUpState ? kThemeStatePressedUp : kThemeStatePressedDown; + return kThemeStatePressed; + } + return kThemeStateActive; +} + +static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor) +{ + // Only do the inflation if the available width/height are too small. Otherwise try to + // fit the glow/check space into the available box's width/height. + int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMargin] * zoomFactor + margins[rightMargin] * zoomFactor); + int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMargin] * zoomFactor + margins[bottomMargin] * zoomFactor); + IntRect result(zoomedRect); + if (widthDelta < 0) { + result.setX(result.x() - margins[leftMargin] * zoomFactor); + result.setWidth(result.width() - widthDelta); + } + if (heightDelta < 0) { + result.setY(result.y() - margins[topMargin] * zoomFactor); + result.setHeight(result.height() - heightDelta); + } + return result; +} + +// Checkboxes + +static const IntSize* checkboxSizes() +{ + static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) }; + return sizes; +} + +static const int* checkboxMargins(NSControlSize controlSize) +{ + static const int margins[3][4] = + { + { 3, 4, 4, 2 }, + { 4, 3, 3, 3 }, + { 4, 3, 3, 3 }, + }; + return margins[controlSize]; +} + +static LengthSize checkboxSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) +{ + // If the width and height are both specified, then we have nothing to do. + if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) + return zoomedSize; + + // Use the font size to determine the intrinsic width of the control. + return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes()); +} + +static NSButtonCell *checkbox(ControlStates states, const IntRect& zoomedRect, float zoomFactor) +{ + static NSButtonCell *checkboxCell; + if (!checkboxCell) { + checkboxCell = [[NSButtonCell alloc] init]; + [checkboxCell setButtonType:NSSwitchButton]; + [checkboxCell setTitle:nil]; + [checkboxCell setAllowsMixedState:YES]; + [checkboxCell setFocusRingType:NSFocusRingTypeExterior]; + } + + // Set the control size based off the rectangle we're painting into. + setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor); + + // Update the various states we respond to. + updateStates(checkboxCell, states); + + return checkboxCell; +} + +// FIXME: Share more code with radio buttons. +static void paintCheckbox(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS + + // Determine the width and height needed for the control and prepare the cell for painting. + NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor); + LocalCurrentGraphicsContext localContext(context); + + context->save(); + + NSControlSize controlSize = [checkboxCell controlSize]; + IntSize zoomedSize = checkboxSizes()[controlSize]; + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); + + if (zoomFactor != 1.0f) { + inflatedRect.setWidth(inflatedRect.width() / zoomFactor); + inflatedRect.setHeight(inflatedRect.height() / zoomFactor); + context->translate(inflatedRect.x(), inflatedRect.y()); + context->scale(FloatSize(zoomFactor, zoomFactor)); + context->translate(-inflatedRect.x(), -inflatedRect.y()); + } + + [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:ThemeMac::ensuredView(scrollView)]; + [checkboxCell setControlView:nil]; + + context->restore(); + + END_BLOCK_OBJC_EXCEPTIONS +} + +// Radio Buttons + +static const IntSize* radioSizes() +{ + static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) }; + return sizes; +} + +static const int* radioMargins(NSControlSize controlSize) +{ + static const int margins[3][4] = + { + { 2, 2, 4, 2 }, + { 3, 2, 3, 2 }, + { 1, 0, 2, 0 }, + }; + return margins[controlSize]; +} + +static LengthSize radioSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) +{ + // If the width and height are both specified, then we have nothing to do. + if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) + return zoomedSize; + + // Use the font size to determine the intrinsic width of the control. + return sizeFromFont(font, zoomedSize, zoomFactor, radioSizes()); +} + +static NSButtonCell *radio(ControlStates states, const IntRect& zoomedRect, float zoomFactor) +{ + static NSButtonCell *radioCell; + if (!radioCell) { + radioCell = [[NSButtonCell alloc] init]; + [radioCell setButtonType:NSRadioButton]; + [radioCell setTitle:nil]; + [radioCell setFocusRingType:NSFocusRingTypeExterior]; + } + + // Set the control size based off the rectangle we're painting into. + setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor); + + // Update the various states we respond to. + updateStates(radioCell, states); + + return radioCell; +} + +static void paintRadio(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) +{ + // Determine the width and height needed for the control and prepare the cell for painting. + NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor); + LocalCurrentGraphicsContext localContext(context); + + context->save(); + + NSControlSize controlSize = [radioCell controlSize]; + IntSize zoomedSize = radioSizes()[controlSize]; + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); + + if (zoomFactor != 1.0f) { + inflatedRect.setWidth(inflatedRect.width() / zoomFactor); + inflatedRect.setHeight(inflatedRect.height() / zoomFactor); + context->translate(inflatedRect.x(), inflatedRect.y()); + context->scale(FloatSize(zoomFactor, zoomFactor)); + context->translate(-inflatedRect.x(), -inflatedRect.y()); + } + + BEGIN_BLOCK_OBJC_EXCEPTIONS + [radioCell drawWithFrame:NSRect(inflatedRect) inView:ThemeMac::ensuredView(scrollView)]; + [radioCell setControlView:nil]; + END_BLOCK_OBJC_EXCEPTIONS + + context->restore(); +} + +// Buttons + +// Buttons really only constrain height. They respect width. +static const IntSize* buttonSizes() +{ + static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; + return sizes; +} + +#if ENABLE(DATALIST) +static const IntSize* listButtonSizes() +{ + static const IntSize sizes[3] = { IntSize(21, 21), IntSize(19, 18), IntSize(17, 16) }; + return sizes; +} +#endif + +static const int* buttonMargins(NSControlSize controlSize) +{ + static const int margins[3][4] = + { + { 4, 6, 7, 6 }, + { 4, 5, 6, 5 }, + { 0, 1, 1, 1 }, + }; + return margins[controlSize]; +} + +enum ButtonCellType { NormalButtonCell, DefaultButtonCell }; + +static NSButtonCell *leakButtonCell(ButtonCellType type) +{ + NSButtonCell *cell = [[NSButtonCell alloc] init]; + [cell setTitle:nil]; + [cell setButtonType:NSMomentaryPushInButton]; + if (type == DefaultButtonCell) + [cell setKeyEquivalent:@"\r"]; + return cell; +} + +static void setUpButtonCell(NSButtonCell *cell, ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor) +{ + // Set the control size based off the rectangle we're painting into. + const IntSize* sizes = buttonSizes(); +#if ENABLE(DATALIST) + if (part == ListButtonPart) { + [cell setBezelStyle:NSRoundedDisclosureBezelStyle]; + sizes = listButtonSizes(); + } else +#endif + if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) { + // Use the square button + if ([cell bezelStyle] != NSShadowlessSquareBezelStyle) + [cell setBezelStyle:NSShadowlessSquareBezelStyle]; + } else if ([cell bezelStyle] != NSRoundedBezelStyle) + [cell setBezelStyle:NSRoundedBezelStyle]; + + setControlSize(cell, sizes, zoomedRect.size(), zoomFactor); + + // Update the various states we respond to. + updateStates(cell, states); +} + +static NSButtonCell *button(ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor) +{ + NSButtonCell *cell; + if (states & DefaultState) { + static NSButtonCell *defaultCell = leakButtonCell(DefaultButtonCell); + cell = defaultCell; + } else { + static NSButtonCell *normalCell = leakButtonCell(NormalButtonCell); + cell = normalCell; + } + setUpButtonCell(cell, part, states, zoomedRect, zoomFactor); + return cell; +} + +static void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS + + // Determine the width and height needed for the control and prepare the cell for painting. + NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor); + LocalCurrentGraphicsContext localContext(context); + + NSControlSize controlSize = [buttonCell controlSize]; +#if ENABLE(DATALIST) + IntSize zoomedSize = (part == ListButtonPart ? listButtonSizes() : buttonSizes())[controlSize]; +#else + IntSize zoomedSize = buttonSizes()[controlSize]; +#endif + zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + IntRect inflatedRect = zoomedRect; + if ([buttonCell bezelStyle] == NSRoundedBezelStyle) { + // Center the button within the available space. + if (inflatedRect.height() > zoomedSize.height()) { + inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomedSize.height()) / 2); + inflatedRect.setHeight(zoomedSize.height()); + } + + // Now inflate it to account for the shadow. + inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); + + if (zoomFactor != 1.0f) { + inflatedRect.setWidth(inflatedRect.width() / zoomFactor); + inflatedRect.setHeight(inflatedRect.height() / zoomFactor); + context->translate(inflatedRect.x(), inflatedRect.y()); + context->scale(FloatSize(zoomFactor, zoomFactor)); + context->translate(-inflatedRect.x(), -inflatedRect.y()); + } + } + + NSView *view = ThemeMac::ensuredView(scrollView); + NSWindow *window = [view window]; + NSButtonCell *previousDefaultButtonCell = [window defaultButtonCell]; + + if (states & DefaultState) { + [window setDefaultButtonCell:buttonCell]; + wkAdvanceDefaultButtonPulseAnimation(buttonCell); + } else if ([previousDefaultButtonCell isEqual:buttonCell]) + [window setDefaultButtonCell:nil]; + + [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view]; + [buttonCell setControlView:nil]; + + if (![previousDefaultButtonCell isEqual:buttonCell]) + [window setDefaultButtonCell:previousDefaultButtonCell]; + + END_BLOCK_OBJC_EXCEPTIONS +} + +// Stepper + +static const IntSize* stepperSizes() +{ + static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(13, 15) }; + return sizes; +} + +// We don't use controlSizeForFont() for steppers because the stepper height +// should be equal to or less than the corresponding text field height, +static NSControlSize stepperControlSizeForFont(const Font& font) +{ + int fontSize = font.pixelSize(); + if (fontSize >= 18) + return NSRegularControlSize; + if (fontSize >= 13) + return NSSmallControlSize; + return NSMiniControlSize; +} + +static void paintStepper(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView*) +{ + // We don't use NSStepperCell because there are no ways to draw an + // NSStepperCell with the up button highlighted. + + HIThemeButtonDrawInfo drawInfo; + drawInfo.version = 0; + drawInfo.state = convertControlStatesToThemeDrawState(kThemeIncDecButton, states); + drawInfo.adornment = kThemeAdornmentDefault; + ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor); + if (controlSize == NSSmallControlSize) + drawInfo.kind = kThemeIncDecButtonSmall; + else if (controlSize == NSMiniControlSize) + drawInfo.kind = kThemeIncDecButtonMini; + else + drawInfo.kind = kThemeIncDecButton; + + IntRect rect(zoomedRect); + context->save(); + if (zoomFactor != 1.0f) { + rect.setWidth(rect.width() / zoomFactor); + rect.setHeight(rect.height() / zoomFactor); + context->translate(rect.x(), rect.y()); + context->scale(FloatSize(zoomFactor, zoomFactor)); + context->translate(-rect.x(), -rect.y()); + } + CGRect bounds(rect); + // Adjust 'bounds' so that HIThemeDrawButton(bounds,...) draws exactly on 'rect'. + CGRect backgroundBounds; + HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds); + if (bounds.origin.x != backgroundBounds.origin.x) + bounds.origin.x += bounds.origin.x - backgroundBounds.origin.x; + if (bounds.origin.y != backgroundBounds.origin.y) + bounds.origin.y += bounds.origin.y - backgroundBounds.origin.y; + HIThemeDrawButton(&bounds, &drawInfo, context->platformContext(), kHIThemeOrientationNormal, 0); + context->restore(); +} + +// This will ensure that we always return a valid NSView, even if ScrollView doesn't have an associated document NSView. +// If the ScrollView doesn't have an NSView, we will return a fake NSView whose sole purpose is to tell AppKit that it's flipped. +NSView *ThemeMac::ensuredView(ScrollView* scrollView) +{ + if (NSView *documentView = scrollView->documentView()) + return documentView; + + // Use a fake flipped view. + static NSView *flippedView = [[WebCoreFlippedView alloc] init]; + + return flippedView; +} + +// Theme overrides + +int ThemeMac::baselinePositionAdjustment(ControlPart part) const +{ + if (part == CheckboxPart || part == RadioPart) + return -2; + return Theme::baselinePositionAdjustment(part); +} + +FontDescription ThemeMac::controlFont(ControlPart part, const Font& font, float zoomFactor) const +{ + switch (part) { + case PushButtonPart: { + FontDescription fontDescription; + fontDescription.setIsAbsoluteSize(true); + fontDescription.setGenericFamily(FontDescription::SerifFamily); + + NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSizeForFont(font)]]; + fontDescription.firstFamily().setFamily([nsFont familyName]); + fontDescription.setComputedSize([nsFont pointSize] * zoomFactor); + fontDescription.setSpecifiedSize([nsFont pointSize] * zoomFactor); + return fontDescription; + } + default: + return Theme::controlFont(part, font, zoomFactor); + } +} + +LengthSize ThemeMac::controlSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor) const +{ + switch (part) { + case CheckboxPart: + return checkboxSize(font, zoomedSize, zoomFactor); + case RadioPart: + return radioSize(font, zoomedSize, zoomFactor); + case PushButtonPart: + // Height is reset to auto so that specified heights can be ignored. + return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes()); +#if ENABLE(DATALIST) + case ListButtonPart: + return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, listButtonSizes()); +#endif + case InnerSpinButtonPart: + // We don't use inner spin buttons on Mac. + return LengthSize(Length(Fixed), Length(Fixed)); + case OuterSpinButtonPart: + if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) + return zoomedSize; + return sizeFromNSControlSize(stepperControlSizeForFont(font), zoomedSize, zoomFactor, stepperSizes()); + default: + return zoomedSize; + } +} + +LengthSize ThemeMac::minimumControlSize(ControlPart part, const Font& font, float zoomFactor) const +{ + switch (part) { + case SquareButtonPart: + case DefaultButtonPart: + case ButtonPart: + case ListButtonPart: + return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed)); + case InnerSpinButtonPart: + // We don't use inner spin buttons on Mac. + return LengthSize(Length(Fixed), Length(Fixed)); + case OuterSpinButtonPart: { + IntSize base = stepperSizes()[NSMiniControlSize]; + return LengthSize(Length(static_cast<int>(base.width() * zoomFactor), Fixed), + Length(static_cast<int>(base.height() * zoomFactor), Fixed)); + } + default: + return Theme::minimumControlSize(part, font, zoomFactor); + } +} + +LengthBox ThemeMac::controlBorder(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const +{ + switch (part) { + case SquareButtonPart: + case DefaultButtonPart: + case ButtonPart: + case ListButtonPart: + return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value()); + default: + return Theme::controlBorder(part, font, zoomedBox, zoomFactor); + } +} + +LengthBox ThemeMac::controlPadding(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const +{ + switch (part) { + case PushButtonPart: { + // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large + // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is + // by definition constrained, since we select mini only for small cramped environments. + // This also guarantees the HTML <button> will match our rendering by default, since we're using a consistent + // padding. + const int padding = 8 * zoomFactor; + return LengthBox(0, padding, 0, padding); + } + default: + return Theme::controlPadding(part, font, zoomedBox, zoomFactor); + } +} + +void ThemeMac::inflateControlPaintRect(ControlPart part, ControlStates states, IntRect& zoomedRect, float zoomFactor) const +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS + switch (part) { + case CheckboxPart: { + // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox + // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. + NSCell *cell = checkbox(states, zoomedRect, zoomFactor); + NSControlSize controlSize = [cell controlSize]; + IntSize zoomedSize = checkboxSizes()[controlSize]; + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); + break; + } + case RadioPart: { + // We inflate the rect as needed to account for padding included in the cell to accommodate the radio button + // shadow". We don't consider this part of the bounds of the control in WebKit. + NSCell *cell = radio(states, zoomedRect, zoomFactor); + NSControlSize controlSize = [cell controlSize]; + IntSize zoomedSize = radioSizes()[controlSize]; + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); + break; + } + case PushButtonPart: + case DefaultButtonPart: + case ButtonPart: { + NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor); + NSControlSize controlSize = [cell controlSize]; + + // We inflate the rect as needed to account for the Aqua button's shadow. + if ([cell bezelStyle] == NSRoundedBezelStyle) { + IntSize zoomedSize = buttonSizes()[controlSize]; + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. + zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); + } + break; + } + case OuterSpinButtonPart: { + static const int stepperMargin[4] = { 0, 0, 0, 0 }; + ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor); + IntSize zoomedSize = stepperSizes()[controlSize]; + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoomFactor); + break; + } + default: + break; + } + END_BLOCK_OBJC_EXCEPTIONS +} + +void ThemeMac::paint(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) const +{ + switch (part) { + case CheckboxPart: + paintCheckbox(states, context, zoomedRect, zoomFactor, scrollView); + break; + case RadioPart: + paintRadio(states, context, zoomedRect, zoomFactor, scrollView); + break; + case PushButtonPart: + case DefaultButtonPart: + case ButtonPart: + case SquareButtonPart: + case ListButtonPart: + paintButton(part, states, context, zoomedRect, zoomFactor, scrollView); + break; + case OuterSpinButtonPart: + paintStepper(states, context, zoomedRect, zoomFactor, scrollView); + break; + default: + break; + } +} + +} diff --git a/Source/WebCore/platform/mac/ThreadCheck.mm b/Source/WebCore/platform/mac/ThreadCheck.mm new file mode 100644 index 0000000..4792191 --- /dev/null +++ b/Source/WebCore/platform/mac/ThreadCheck.mm @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#import "config.h" +#import "ThreadCheck.h" + +#import <wtf/HashSet.h> +#import <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> + +namespace WebCore { + +static bool didReadThreadViolationBehaviorFromUserDefaults = false; +static bool threadViolationBehaviorIsDefault = true; +static ThreadViolationBehavior threadViolationBehavior[MaximumThreadViolationRound] = { RaiseExceptionOnThreadViolation, RaiseExceptionOnThreadViolation }; + +static void readThreadViolationBehaviorFromUserDefaults() +{ + didReadThreadViolationBehaviorFromUserDefaults = true; + + ThreadViolationBehavior newBehavior = LogOnFirstThreadViolation; + NSString *threadCheckLevel = [[NSUserDefaults standardUserDefaults] stringForKey:@"WebCoreThreadCheck"]; + if (!threadCheckLevel) + return; + + if ([threadCheckLevel isEqualToString:@"None"]) + newBehavior = NoThreadCheck; + else if ([threadCheckLevel isEqualToString:@"Exception"]) + newBehavior = RaiseExceptionOnThreadViolation; + else if ([threadCheckLevel isEqualToString:@"Log"]) + newBehavior = LogOnThreadViolation; + else if ([threadCheckLevel isEqualToString:@"LogOnce"]) + newBehavior = LogOnFirstThreadViolation; + else + ASSERT_NOT_REACHED(); + + threadViolationBehaviorIsDefault = false; + + for (unsigned i = 0; i < MaximumThreadViolationRound; ++i) + threadViolationBehavior[i] = newBehavior; +} + +void setDefaultThreadViolationBehavior(ThreadViolationBehavior behavior, ThreadViolationRound round) +{ + ASSERT(round < MaximumThreadViolationRound); + if (round >= MaximumThreadViolationRound) + return; + if (!didReadThreadViolationBehaviorFromUserDefaults) + readThreadViolationBehaviorFromUserDefaults(); + if (threadViolationBehaviorIsDefault) + threadViolationBehavior[round] = behavior; +} + +void reportThreadViolation(const char* function, ThreadViolationRound round) +{ + ASSERT(round < MaximumThreadViolationRound); + if (round >= MaximumThreadViolationRound) + return; + if (!didReadThreadViolationBehaviorFromUserDefaults) + readThreadViolationBehaviorFromUserDefaults(); + if (threadViolationBehavior[round] == NoThreadCheck) + return; + if (pthread_main_np()) + return; + WebCoreReportThreadViolation(function, round); +} + +} // namespace WebCore + +// Split out the actual reporting of the thread violation to make it easier to set a breakpoint +void WebCoreReportThreadViolation(const char* function, WebCore::ThreadViolationRound round) +{ + using namespace WebCore; + + ASSERT(round < MaximumThreadViolationRound); + if (round >= MaximumThreadViolationRound) + return; + + DEFINE_STATIC_LOCAL(HashSet<String>, loggedFunctions, ()); + switch (threadViolationBehavior[round]) { + case NoThreadCheck: + break; + case LogOnFirstThreadViolation: + if (loggedFunctions.add(function).second) { + NSLog(@"WebKit Threading Violation - %s called from secondary thread", function); + NSLog(@"Additional threading violations for this function will not be logged."); + } + break; + case LogOnThreadViolation: + NSLog(@"WebKit Threading Violation - %s called from secondary thread", function); + break; + case RaiseExceptionOnThreadViolation: + [NSException raise:@"WebKitThreadingException" format:@"%s was called from a secondary thread", function]; + break; + } +} diff --git a/Source/WebCore/platform/mac/WebCoreKeyGenerator.h b/Source/WebCore/platform/mac/WebCoreKeyGenerator.h new file mode 100644 index 0000000..c9260e1 --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreKeyGenerator.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2003 Apple Computer, 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. + */ + +@interface WebCoreKeyGenerator : NSObject + ++ (WebCoreKeyGenerator *)sharedGenerator; +- (NSArray *)strengthMenuItemTitles; +- (NSString *)signedPublicKeyAndChallengeStringWithStrengthIndex:(unsigned)index challenge:(NSString *)challenge pageURL:(NSURL *)pageURL; + +@end diff --git a/Source/WebCore/platform/mac/WebCoreKeyGenerator.m b/Source/WebCore/platform/mac/WebCoreKeyGenerator.m new file mode 100644 index 0000000..a1e780c --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreKeyGenerator.m @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2003 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. + */ + +#import "config.h" +#import "WebCoreKeyGenerator.h" + +#import <wtf/Assertions.h> +#import <wtf/UnusedParam.h> + +static WebCoreKeyGenerator *sharedGenerator; + +@implementation WebCoreKeyGenerator + ++ (WebCoreKeyGenerator *)sharedGenerator +{ + return sharedGenerator; +} + +- init +{ + ASSERT(!sharedGenerator); + [super init]; + sharedGenerator = [self retain]; + return self; +} + +- (NSArray *)strengthMenuItemTitles +{ + return nil; +} + +- (NSString *)signedPublicKeyAndChallengeStringWithStrengthIndex:(unsigned)unusedIndex challenge:(NSString *)unusedChallenge pageURL:(NSURL *)unusedPageURL +{ + UNUSED_PARAM(unusedIndex); + UNUSED_PARAM(unusedChallenge); + UNUSED_PARAM(unusedPageURL); + + return nil; +} + +@end diff --git a/Source/WebCore/platform/mac/WebCoreNSStringExtras.h b/Source/WebCore/platform/mac/WebCoreNSStringExtras.h new file mode 100644 index 0000000..f040f16 --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreNSStringExtras.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2005, 2007 Apple Computer, 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 <ApplicationServices/ApplicationServices.h> +#include <objc/objc.h> + +#ifdef __OBJC__ +#include <Foundation/Foundation.h> +@class NSString; +#else +typedef struct NSString NSString; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL stringIsCaseInsensitiveEqualToString(NSString *first, NSString *second); +BOOL hasCaseInsensitiveSuffix(NSString *string, NSString *suffix); +BOOL hasCaseInsensitiveSubstring(NSString *string, NSString *substring); +NSString *filenameByFixingIllegalCharacters(NSString *string); +CFStringEncoding stringEncodingForResource(Handle resource); + +#ifdef __cplusplus +} +#endif diff --git a/Source/WebCore/platform/mac/WebCoreNSStringExtras.mm b/Source/WebCore/platform/mac/WebCoreNSStringExtras.mm new file mode 100644 index 0000000..d6c3f0c --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreNSStringExtras.mm @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2005, 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. + */ + +#import "config.h" +#import "WebCoreNSStringExtras.h" + +#import <wtf/RetainPtr.h> + +BOOL stringIsCaseInsensitiveEqualToString(NSString *first, NSString *second) +{ + return [first compare:second options:(NSCaseInsensitiveSearch|NSLiteralSearch)] == NSOrderedSame; +} + +BOOL hasCaseInsensitiveSuffix(NSString *string, NSString *suffix) +{ + return [string rangeOfString:suffix options:(NSCaseInsensitiveSearch | NSBackwardsSearch | NSAnchoredSearch)].location != NSNotFound; +} + +BOOL hasCaseInsensitiveSubstring(NSString *string, NSString *substring) +{ + return [string rangeOfString:substring options:NSCaseInsensitiveSearch].location != NSNotFound; +} + +NSString *filenameByFixingIllegalCharacters(NSString *string) +{ + NSMutableString *filename = [[string mutableCopy] autorelease]; + + // Strip null characters. + unichar nullChar = 0; + [filename replaceOccurrencesOfString:[NSString stringWithCharacters:&nullChar length:0] withString:@"" options:0 range:NSMakeRange(0, [filename length])]; + + // Replace "/" with "-". + [filename replaceOccurrencesOfString:@"/" withString:@"-" options:0 range:NSMakeRange(0, [filename length])]; + + // Replace ":" with "-". + [filename replaceOccurrencesOfString:@":" withString:@"-" options:0 range:NSMakeRange(0, [filename length])]; + + // Strip leading dots. + while ([filename hasPrefix:@"."]) { + [filename deleteCharactersInRange:NSMakeRange(0,1)]; + } + + return filename; +} + +CFStringEncoding stringEncodingForResource(Handle resource) +{ + short resRef = HomeResFile(resource); + if (ResError() != noErr) + return NSMacOSRomanStringEncoding; + + // Get the FSRef for the current resource file + FSRef fref; + OSStatus error = FSGetForkCBInfo(resRef, 0, NULL, NULL, NULL, &fref, NULL); + if (error != noErr) + return NSMacOSRomanStringEncoding; + + RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateFromFSRef(NULL, &fref)); + if (!url) + return NSMacOSRomanStringEncoding; + + NSString *path = [(NSURL *)url.get() path]; + + // Get the lproj directory name + path = [path stringByDeletingLastPathComponent]; + if (!stringIsCaseInsensitiveEqualToString([path pathExtension], @"lproj")) + return NSMacOSRomanStringEncoding; + + NSString *directoryName = [[path stringByDeletingPathExtension] lastPathComponent]; + RetainPtr<CFStringRef> locale(AdoptCF, CFLocaleCreateCanonicalLocaleIdentifierFromString(NULL, (CFStringRef)directoryName)); + if (!locale) + return NSMacOSRomanStringEncoding; + + LangCode lang; + RegionCode region; + error = LocaleStringToLangAndRegionCodes([(NSString *)locale.get() UTF8String], &lang, ®ion); + if (error != noErr) + return NSMacOSRomanStringEncoding; + + TextEncoding encoding; + error = UpgradeScriptInfoToTextEncoding(kTextScriptDontCare, lang, region, NULL, &encoding); + if (error != noErr) + return NSMacOSRomanStringEncoding; + + return encoding; +} + diff --git a/Source/WebCore/platform/mac/WebCoreObjCExtras.h b/Source/WebCore/platform/mac/WebCoreObjCExtras.h new file mode 100644 index 0000000..7e699a5 --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreObjCExtras.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple 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 <objc/objc.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void WebCoreObjCFinalizeOnMainThread(Class cls); + +// The 'Class' that should be passed in here is the class of the +// object that implements the dealloc method that this function is called from. +bool WebCoreObjCScheduleDeallocateOnMainThread(Class cls, id object); + +#ifdef __cplusplus +} +#endif diff --git a/Source/WebCore/platform/mac/WebCoreObjCExtras.mm b/Source/WebCore/platform/mac/WebCoreObjCExtras.mm new file mode 100644 index 0000000..05d3e01 --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreObjCExtras.mm @@ -0,0 +1,82 @@ +/* + * 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. + */ + +#include "config.h" +#include "WebCoreObjCExtras.h" + +#include <objc/objc-auto.h> +#include <objc/objc-runtime.h> +#include <wtf/Assertions.h> +#include <wtf/MainThread.h> +#include <wtf/Threading.h> +#include <wtf/UnusedParam.h> + +void WebCoreObjCFinalizeOnMainThread(Class cls) +{ + // This method relies on threading being initialized by the caller, otherwise + // WebCoreObjCScheduleDeallocateOnMainThread will crash. +#if !defined(BUILDING_ON_TIGER) && !defined(DONT_FINALIZE_ON_MAIN_THREAD) + objc_finalizeOnMainThread(cls); +#else + UNUSED_PARAM(cls); +#endif +} + +#ifdef BUILDING_ON_TIGER +static inline IMP method_getImplementation(Method method) +{ + return method->method_imp; +} +#endif + +typedef std::pair<Class, id> ClassAndIdPair; + +static void deallocCallback(void* context) +{ + ClassAndIdPair* pair = static_cast<ClassAndIdPair*>(context); + + Method method = class_getInstanceMethod(pair->first, @selector(dealloc)); + + IMP imp = method_getImplementation(method); + imp(pair->second, @selector(dealloc)); + + delete pair; +} + +bool WebCoreObjCScheduleDeallocateOnMainThread(Class cls, id object) +{ + ASSERT([object isKindOfClass:cls]); + + if (isMainThread()) + return false; + + ClassAndIdPair* pair = new ClassAndIdPair(cls, object); + callOnMainThread(deallocCallback, pair); + return true; +} + diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.h b/Source/WebCore/platform/mac/WebCoreSystemInterface.h new file mode 100644 index 0000000..0c78c23 --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.h @@ -0,0 +1,193 @@ +/* + * Copyright 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 WebCoreSystemInterface_h +#define WebCoreSystemInterface_h + +#include <ApplicationServices/ApplicationServices.h> +#include <objc/objc.h> + +#if PLATFORM(MAC) && PLATFORM(CA) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#include <IOSurface/IOSurface.h> +#endif + +typedef struct _NSRange NSRange; + +#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES +typedef struct CGPoint NSPoint; +typedef struct CGRect NSRect; +#else +typedef struct _NSPoint NSPoint; +typedef struct _NSRect NSRect; +#endif + +#ifdef __OBJC__ +@class NSArray; +@class NSButtonCell; +@class NSData; +@class NSDate; +@class NSEvent; +@class NSFont; +@class NSImage; +@class NSMenu; +@class NSMutableURLRequest; +@class NSString; +@class NSTextFieldCell; +@class NSURLConnection; +@class NSURLRequest; +@class NSURLResponse; +@class NSView; +@class QTMovie; +@class QTMovieView; +#else +class NSArray; +class NSButtonCell; +class NSData; +class NSDate; +class NSEvent; +class NSFont; +class NSImage; +class NSMenu; +class NSMutableArray; +class NSMutableURLRequest; +class NSURLRequest; +class NSString; +class NSTextFieldCell; +class NSURLConnection; +class NSURLResponse; +class NSView; +class QTMovie; +class QTMovieView; +#endif + +extern "C" { + +// In alphabetical order. + +extern void (*wkAdvanceDefaultButtonPulseAnimation)(NSButtonCell *); +extern BOOL (*wkCGContextGetShouldSmoothFonts)(CGContextRef); +extern CFReadStreamRef (*wkCreateCustomCFReadStream)(void *(*formCreate)(CFReadStreamRef, void *), + void (*formFinalize)(CFReadStreamRef, void *), + Boolean (*formOpen)(CFReadStreamRef, CFStreamError *, Boolean *, void *), + CFIndex (*formRead)(CFReadStreamRef, UInt8 *, CFIndex, CFStreamError *, Boolean *, void *), + Boolean (*formCanRead)(CFReadStreamRef, void *), + void (*formClose)(CFReadStreamRef, void *), + void (*formSchedule)(CFReadStreamRef, CFRunLoopRef, CFStringRef, void *), + void (*formUnschedule)(CFReadStreamRef, CFRunLoopRef, CFStringRef, void *), + void *context); +extern CFStringRef (*wkCopyCFLocalizationPreferredName)(CFStringRef); +extern NSString* (*wkCopyNSURLResponseStatusLine)(NSURLResponse*); +extern id (*wkCreateNSURLConnectionDelegateProxy)(void); +extern void (*wkDrawBezeledTextFieldCell)(NSRect, BOOL enabled); +extern void (*wkDrawTextFieldCellFocusRing)(NSTextFieldCell*, NSRect); +extern void (*wkDrawCapsLockIndicator)(CGContextRef, CGRect); +extern void (*wkDrawBezeledTextArea)(NSRect, BOOL enabled); +extern void (*wkDrawFocusRing)(CGContextRef, CGColorRef, int radius); +extern NSFont* (*wkGetFontInLanguageForRange)(NSFont*, NSString*, NSRange); +extern NSFont* (*wkGetFontInLanguageForCharacter)(NSFont*, UniChar); +extern BOOL (*wkGetGlyphTransformedAdvances)(CGFontRef, NSFont*, CGAffineTransform*, ATSGlyphRef*, CGSize* advance); +extern void (*wkDrawMediaSliderTrack)(int themeStyle, CGContextRef context, CGRect rect, float timeLoaded, float currentTime, + float duration, unsigned state); +extern void (*wkDrawMediaUIPart)(int part, int themeStyle, CGContextRef context, CGRect rect, unsigned state); +extern NSString* (*wkGetPreferredExtensionForMIMEType)(NSString*); +extern NSArray* (*wkGetExtensionsForMIMEType)(NSString*); +extern NSString* (*wkGetMIMETypeForExtension)(NSString*); +extern ATSUFontID (*wkGetNSFontATSUFontId)(NSFont*); +extern double (*wkGetNSURLResponseCalculatedExpiration)(NSURLResponse *response); +extern NSDate *(*wkGetNSURLResponseLastModifiedDate)(NSURLResponse *response); +extern BOOL (*wkGetNSURLResponseMustRevalidate)(NSURLResponse *response); +extern void (*wkGetWheelEventDeltas)(NSEvent*, float* deltaX, float* deltaY, BOOL* continuous); +extern BOOL (*wkHitTestMediaUIPart)(int part, int themeStyle, CGRect bounds, CGPoint point); +extern void (*wkMeasureMediaUIPart)(int part, int themeStyle, CGRect *bounds, CGSize *naturalSize); +extern BOOL (*wkMediaControllerThemeAvailable)(int themeStyle); +extern void (*wkPopupMenu)(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*); +extern unsigned (*wkQTIncludeOnlyModernMediaFileTypes)(void); +extern int (*wkQTMovieDataRate)(QTMovie*); +extern void (*wkQTMovieDisableComponent)(uint32_t[5]); +extern float (*wkQTMovieMaxTimeLoaded)(QTMovie*); +extern NSString *(*wkQTMovieMaxTimeLoadedChangeNotification)(void); +extern float (*wkQTMovieMaxTimeSeekable)(QTMovie*); +extern int (*wkQTMovieGetType)(QTMovie*); +extern BOOL (*wkQTMovieHasClosedCaptions)(QTMovie*); +extern void (*wkQTMovieSetShowClosedCaptions)(QTMovie*, BOOL); +extern void (*wkQTMovieSelectPreferredAlternates)(QTMovie*); +extern void (*wkQTMovieViewSetDrawSynchronously)(QTMovieView*, BOOL); +extern void (*wkSetCGFontRenderingMode)(CGContextRef, NSFont*); +extern void (*wkSetCookieStoragePrivateBrowsingEnabled)(BOOL); +extern void (*wkSetDragImage)(NSImage*, NSPoint offset); +extern void (*wkSetNSURLConnectionDefersCallbacks)(NSURLConnection *, BOOL); +extern void (*wkSetNSURLRequestShouldContentSniff)(NSMutableURLRequest *, BOOL); +extern void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform); +extern void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint); +extern CGAffineTransform (*wkGetUserToBaseCTM)(CGContextRef); +extern void (*wkSetUpFontCache)(); +extern void (*wkSignalCFReadStreamEnd)(CFReadStreamRef stream); +extern void (*wkSignalCFReadStreamError)(CFReadStreamRef stream, CFStreamError *error); +extern void (*wkSignalCFReadStreamHasBytes)(CFReadStreamRef stream); +extern unsigned (*wkInitializeMaximumHTTPConnectionCountPerHost)(unsigned preferredConnectionCount); +extern void (*wkSetCONNECTProxyForStream)(CFReadStreamRef, CFStringRef proxyHost, CFNumberRef proxyPort); +extern void (*wkSetCONNECTProxyAuthorizationForStream)(CFReadStreamRef, CFStringRef proxyAuthorizationString); +extern CFHTTPMessageRef (*wkCopyCONNECTProxyResponse)(CFReadStreamRef, CFURLRef responseURL); +extern BOOL (*wkIsLatchingWheelEvent)(NSEvent *); + +#ifndef BUILDING_ON_TIGER +extern void (*wkGetGlyphsForCharacters)(CGFontRef, const UniChar[], CGGlyph[], size_t); +#else +#define GLYPH_VECTOR_SIZE (50 * 32) + +extern void (*wkClearGlyphVector)(void* glyphs); +extern OSStatus (*wkConvertCharToGlyphs)(void* styleGroup, const UniChar*, unsigned numCharacters, void* glyphs); +extern CFStringRef (*wkCopyFullFontName)(CGFontRef font); +extern OSStatus (*wkGetATSStyleGroup)(ATSUStyle, void** styleGroup); +extern CGFontRef (*wkGetCGFontFromNSFont)(NSFont*); +extern void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm); +extern ATSLayoutRecord* (*wkGetGlyphVectorFirstRecord)(void* glyphVector); +extern void* wkGetGlyphsForCharacters; +extern int (*wkGetGlyphVectorNumGlyphs)(void* glyphVector); +extern size_t (*wkGetGlyphVectorRecordSize)(void* glyphVector); +extern OSStatus (*wkInitializeGlyphVector)(int count, void* glyphs); +extern void (*wkReleaseStyleGroup)(void* group); +extern BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *); +#endif + +extern BOOL (*wkUseSharedMediaUI)(); + +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +extern void* wkGetHyphenationLocationBeforeIndex; +#else +extern CFIndex (*wkGetHyphenationLocationBeforeIndex)(CFStringRef string, CFIndex index); +#endif + +extern CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*); +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +extern CTTypesetterRef (*wkCreateCTTypesetterWithUniCharProviderAndOptions)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*, CFDictionaryRef options); + +extern CGContextRef (*wkIOSurfaceContextCreate)(IOSurfaceRef surface, unsigned width, unsigned height, CGColorSpaceRef colorSpace); +extern CGImageRef (*wkIOSurfaceContextCreateImage)(CGContextRef context); +#endif + +} + +#endif diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.mm b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm new file mode 100644 index 0000000..df3c77c --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm @@ -0,0 +1,128 @@ +/* + * Copyright 2006, 2007, 2008, 2009, 2010 Apple Computer, 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. + */ + +#import "config.h" +#import "WebCoreSystemInterface.h" +#import <Foundation/Foundation.h> + +void (*wkAdvanceDefaultButtonPulseAnimation)(NSButtonCell *); +BOOL (*wkCGContextGetShouldSmoothFonts)(CGContextRef); +CFStringRef (*wkCopyCFLocalizationPreferredName)(CFStringRef); +NSString* (*wkCopyNSURLResponseStatusLine)(NSURLResponse*); +NSString* (*wkCreateURLPasteboardFlavorTypeName)(void); +NSString* (*wkCreateURLNPasteboardFlavorTypeName)(void); +void (*wkDrawBezeledTextFieldCell)(NSRect, BOOL enabled); +void (*wkDrawTextFieldCellFocusRing)(NSTextFieldCell*, NSRect); +void (*wkDrawCapsLockIndicator)(CGContextRef, CGRect); +void (*wkDrawBezeledTextArea)(NSRect, BOOL enabled); +void (*wkDrawFocusRing)(CGContextRef, CGColorRef, int radius); +NSFont* (*wkGetFontInLanguageForRange)(NSFont*, NSString*, NSRange); +NSFont* (*wkGetFontInLanguageForCharacter)(NSFont*, UniChar); +BOOL (*wkGetGlyphTransformedAdvances)(CGFontRef, NSFont*, CGAffineTransform*, ATSGlyphRef*, CGSize* advance); +void (*wkDrawMediaSliderTrack)(int themeStyle, CGContextRef context, CGRect rect, float timeLoaded, float currentTime, + float duration, unsigned state); +BOOL (*wkHitTestMediaUIPart)(int part, int themeStyle, CGRect bounds, CGPoint point); +void (*wkDrawMediaUIPart)(int part, int themeStyle, CGContextRef context, CGRect rect, unsigned state); +void (*wkMeasureMediaUIPart)(int part, int themeStyle, CGRect *bounds, CGSize *naturalSize); +BOOL (*wkMediaControllerThemeAvailable)(int themeStyle); +NSString* (*wkGetPreferredExtensionForMIMEType)(NSString*); +NSArray* (*wkGetExtensionsForMIMEType)(NSString*); +NSString* (*wkGetMIMETypeForExtension)(NSString*); +NSTimeInterval (*wkGetNSURLResponseCalculatedExpiration)(NSURLResponse *response); +NSDate *(*wkGetNSURLResponseLastModifiedDate)(NSURLResponse *response); +BOOL (*wkGetNSURLResponseMustRevalidate)(NSURLResponse *response); +void (*wkGetWheelEventDeltas)(NSEvent*, float* deltaX, float* deltaY, BOOL* continuous); +void (*wkPopupMenu)(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*); +unsigned (*wkQTIncludeOnlyModernMediaFileTypes)(void); +int (*wkQTMovieDataRate)(QTMovie*); +void (*wkQTMovieDisableComponent)(uint32_t[5]); +float (*wkQTMovieMaxTimeLoaded)(QTMovie*); +NSString *(*wkQTMovieMaxTimeLoadedChangeNotification)(void); +float (*wkQTMovieMaxTimeSeekable)(QTMovie*); +int (*wkQTMovieGetType)(QTMovie*); +BOOL (*wkQTMovieHasClosedCaptions)(QTMovie*); +void (*wkQTMovieSetShowClosedCaptions)(QTMovie*, BOOL); +void (*wkQTMovieSelectPreferredAlternates)(QTMovie*); +void (*wkQTMovieViewSetDrawSynchronously)(QTMovieView*, BOOL); +void (*wkSetCGFontRenderingMode)(CGContextRef, NSFont*); +void (*wkSetCookieStoragePrivateBrowsingEnabled)(BOOL); +void (*wkSetDragImage)(NSImage*, NSPoint offset); +void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform); +void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint point); +CGAffineTransform (*wkGetUserToBaseCTM)(CGContextRef); +void (*wkSetUpFontCache)(); +void (*wkSignalCFReadStreamEnd)(CFReadStreamRef stream); +void (*wkSignalCFReadStreamHasBytes)(CFReadStreamRef stream); +void (*wkSignalCFReadStreamError)(CFReadStreamRef stream, CFStreamError *error); +CFReadStreamRef (*wkCreateCustomCFReadStream)(void *(*formCreate)(CFReadStreamRef, void *), + void (*formFinalize)(CFReadStreamRef, void *), + Boolean (*formOpen)(CFReadStreamRef, CFStreamError *, Boolean *, void *), + CFIndex (*formRead)(CFReadStreamRef, UInt8 *, CFIndex, CFStreamError *, Boolean *, void *), + Boolean (*formCanRead)(CFReadStreamRef, void *), + void (*formClose)(CFReadStreamRef, void *), + void (*formSchedule)(CFReadStreamRef, CFRunLoopRef, CFStringRef, void *), + void (*formUnschedule)(CFReadStreamRef, CFRunLoopRef, CFStringRef, void *), + void *context); +void (*wkSetNSURLConnectionDefersCallbacks)(NSURLConnection *, BOOL); +void (*wkSetNSURLRequestShouldContentSniff)(NSMutableURLRequest *, BOOL); +id (*wkCreateNSURLConnectionDelegateProxy)(void); +unsigned (*wkInitializeMaximumHTTPConnectionCountPerHost)(unsigned preferredConnectionCount); +void (*wkSetCONNECTProxyForStream)(CFReadStreamRef, CFStringRef proxyHost, CFNumberRef proxyPort); +void (*wkSetCONNECTProxyAuthorizationForStream)(CFReadStreamRef, CFStringRef proxyAuthorizationString); +CFHTTPMessageRef (*wkCopyCONNECTProxyResponse)(CFReadStreamRef, CFURLRef responseURL); +BOOL (*wkIsLatchingWheelEvent)(NSEvent *); + +#ifndef BUILDING_ON_TIGER +void (*wkGetGlyphsForCharacters)(CGFontRef, const UniChar[], CGGlyph[], size_t); +#else +void (*wkClearGlyphVector)(void* glyphs); +OSStatus (*wkConvertCharToGlyphs)(void* styleGroup, const UniChar*, unsigned numCharacters, void* glyphs); +CFStringRef (*wkCopyFullFontName)(CGFontRef font); +OSStatus (*wkGetATSStyleGroup)(ATSUStyle, void** styleGroup); +CGFontRef (*wkGetCGFontFromNSFont)(NSFont*); +void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm); +ATSLayoutRecord* (*wkGetGlyphVectorFirstRecord)(void* glyphVector); +void* wkGetGlyphsForCharacters; +int (*wkGetGlyphVectorNumGlyphs)(void* glyphVector); +size_t (*wkGetGlyphVectorRecordSize)(void* glyphVector); +OSStatus (*wkInitializeGlyphVector)(int count, void* glyphs); +void (*wkReleaseStyleGroup)(void* group); +ATSUFontID (*wkGetNSFontATSUFontId)(NSFont*); +BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *); +#endif + +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +void* wkGetHyphenationLocationBeforeIndex; +#else +CFIndex (*wkGetHyphenationLocationBeforeIndex)(CFStringRef string, CFIndex index); +#endif + +CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*); +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +CTTypesetterRef (*wkCreateCTTypesetterWithUniCharProviderAndOptions)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*, CFDictionaryRef options); + +CGContextRef (*wkIOSurfaceContextCreate)(IOSurfaceRef surface, unsigned width, unsigned height, CGColorSpaceRef colorSpace); +CGImageRef (*wkIOSurfaceContextCreateImage)(CGContextRef context); +#endif diff --git a/Source/WebCore/platform/mac/WebCoreView.h b/Source/WebCore/platform/mac/WebCoreView.h new file mode 100644 index 0000000..15d5b13 --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreView.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2003 Apple Computer, 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. + */ + +@interface NSView (WebCoreView) +- (NSView *)_webcore_effectiveFirstResponder; +@end diff --git a/Source/WebCore/platform/mac/WebCoreView.m b/Source/WebCore/platform/mac/WebCoreView.m new file mode 100644 index 0000000..e2f11fa --- /dev/null +++ b/Source/WebCore/platform/mac/WebCoreView.m @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2003 Apple Computer, 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. + */ + +#import "config.h" +#import "WebCoreView.h" + +@interface NSClipView (WebCoreView) +- (NSView *)_webcore_effectiveFirstResponder; +@end + +@interface NSScrollView (WebCoreView) +- (NSView *)_webcore_effectiveFirstResponder; +@end + +@implementation NSView (WebCoreView) + +- (NSView *)_webcore_effectiveFirstResponder +{ + return self; +} + +@end + +@implementation NSClipView (WebCoreView) + +- (NSView *)_webcore_effectiveFirstResponder +{ + NSView *view = [self documentView]; + return view ? [view _webcore_effectiveFirstResponder] : [super _webcore_effectiveFirstResponder]; +} + +@end + +@implementation NSScrollView (WebCoreView) + +- (NSView *)_webcore_effectiveFirstResponder +{ + NSView *view = [self contentView]; + return view ? [view _webcore_effectiveFirstResponder] : [super _webcore_effectiveFirstResponder]; +} + +@end + diff --git a/Source/WebCore/platform/mac/WebFontCache.h b/Source/WebCore/platform/mac/WebFontCache.h new file mode 100644 index 0000000..380f271 --- /dev/null +++ b/Source/WebCore/platform/mac/WebFontCache.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <AppKit/NSFontManager.h> +#import <wtf/Vector.h> + +// This interface exists so that third party products (like Silk) can patch in to an Obj-C method to manipulate WebKit's font caching/substitution. +@interface WebFontCache : NSObject ++ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits weight:(int)desiredWeight size:(float)size; ++ (void)getTraits:(Vector<unsigned>&)traitsMasks inFamily:(NSString *)desiredFamily; + +// This older version of the interface is relied upon by some clients. WebCore doesn't use it. ++ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits size:(float)size; +@end diff --git a/Source/WebCore/platform/mac/WebFontCache.mm b/Source/WebCore/platform/mac/WebFontCache.mm new file mode 100644 index 0000000..22e6291 --- /dev/null +++ b/Source/WebCore/platform/mac/WebFontCache.mm @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple 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. + */ + +#import "config.h" +#import "WebFontCache.h" + +#import "FontTraitsMask.h" +#import <AppKit/AppKit.h> +#import <Foundation/Foundation.h> +#import <math.h> +#import <wtf/UnusedParam.h> + +using namespace WebCore; + +#ifdef BUILDING_ON_TIGER +typedef int NSInteger; +#endif + +#define SYNTHESIZED_FONT_TRAITS (NSBoldFontMask | NSItalicFontMask) + +#define IMPORTANT_FONT_TRAITS (0 \ + | NSCompressedFontMask \ + | NSCondensedFontMask \ + | NSExpandedFontMask \ + | NSItalicFontMask \ + | NSNarrowFontMask \ + | NSPosterFontMask \ + | NSSmallCapsFontMask \ +) + +static BOOL acceptableChoice(NSFontTraitMask desiredTraits, NSFontTraitMask candidateTraits) +{ + desiredTraits &= ~SYNTHESIZED_FONT_TRAITS; + return (candidateTraits & desiredTraits) == desiredTraits; +} + +static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, + NSFontTraitMask chosenTraits, int chosenWeight, + NSFontTraitMask candidateTraits, int candidateWeight) +{ + if (!acceptableChoice(desiredTraits, candidateTraits)) + return NO; + + // A list of the traits we care about. + // The top item in the list is the worst trait to mismatch; if a font has this + // and we didn't ask for it, we'd prefer any other font in the family. + const NSFontTraitMask masks[] = { + NSPosterFontMask, + NSSmallCapsFontMask, + NSItalicFontMask, + NSCompressedFontMask, + NSCondensedFontMask, + NSExpandedFontMask, + NSNarrowFontMask, + 0 + }; + + int i = 0; + NSFontTraitMask mask; + while ((mask = masks[i++])) { + BOOL desired = (desiredTraits & mask) != 0; + BOOL chosenHasUnwantedTrait = desired != ((chosenTraits & mask) != 0); + BOOL candidateHasUnwantedTrait = desired != ((candidateTraits & mask) != 0); + if (!candidateHasUnwantedTrait && chosenHasUnwantedTrait) + return YES; + if (!chosenHasUnwantedTrait && candidateHasUnwantedTrait) + return NO; + } + + int chosenWeightDeltaMagnitude = abs(chosenWeight - desiredWeight); + int candidateWeightDeltaMagnitude = abs(candidateWeight - desiredWeight); + + // If both are the same distance from the desired weight, prefer the candidate if it is further from medium. + if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude) + return abs(candidateWeight - 6) > abs(chosenWeight - 6); + + // Otherwise, prefer the one closer to the desired weight. + return candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude; +} + +// Workaround for <rdar://problem/5781372>. +static inline void fixUpWeight(NSInteger& weight, NSString *fontName) +{ +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + UNUSED_PARAM(weight); + UNUSED_PARAM(fontName); +#else + if (weight == 3 && [fontName rangeOfString:@"ultralight" options:NSCaseInsensitiveSearch | NSBackwardsSearch | NSLiteralSearch].location != NSNotFound) + weight = 2; +#endif +} + +static inline FontTraitsMask toTraitsMask(NSFontTraitMask appKitTraits, NSInteger appKitWeight) +{ + return static_cast<FontTraitsMask>(((appKitTraits & NSFontItalicTrait) ? FontStyleItalicMask : FontStyleNormalMask) + | FontVariantNormalMask + | (appKitWeight == 1 ? FontWeight100Mask : + appKitWeight == 2 ? FontWeight200Mask : + appKitWeight <= 4 ? FontWeight300Mask : + appKitWeight == 5 ? FontWeight400Mask : + appKitWeight == 6 ? FontWeight500Mask : + appKitWeight <= 8 ? FontWeight600Mask : + appKitWeight == 9 ? FontWeight700Mask : + appKitWeight <= 11 ? FontWeight800Mask : + FontWeight900Mask)); +} + +@implementation WebFontCache + ++ (void)getTraits:(Vector<unsigned>&)traitsMasks inFamily:(NSString *)desiredFamily +{ + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + + NSEnumerator *e = [[fontManager availableFontFamilies] objectEnumerator]; + NSString *availableFamily; + while ((availableFamily = [e nextObject])) { + if ([desiredFamily caseInsensitiveCompare:availableFamily] == NSOrderedSame) + break; + } + + if (!availableFamily) { + // Match by PostScript name. + NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnumerator]; + NSString *availableFont; + while ((availableFont = [availableFonts nextObject])) { + if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrderedSame) { + NSFont *font = [NSFont fontWithName:availableFont size:10]; + NSInteger weight = [fontManager weightOfFont:font]; + fixUpWeight(weight, desiredFamily); + traitsMasks.append(toTraitsMask([fontManager traitsOfFont:font], weight)); + break; + } + } + return; + } + + NSArray *fonts = [fontManager availableMembersOfFontFamily:availableFamily]; + unsigned n = [fonts count]; + unsigned i; + for (i = 0; i < n; i++) { + NSArray *fontInfo = [fonts objectAtIndex:i]; + // Array indices must be hard coded because of lame AppKit API. + NSString *fontFullName = [fontInfo objectAtIndex:0]; + NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue]; + fixUpWeight(fontWeight, fontFullName); + + NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValue]; + traitsMasks.append(toTraitsMask(fontTraits, fontWeight)); + } +} + +// Family name is somewhat of a misnomer here. We first attempt to find an exact match +// comparing the desiredFamily to the PostScript name of the installed fonts. If that fails +// we then do a search based on the family names of the installed fonts. ++ (NSFont *)internalFontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits weight:(int)desiredWeight size:(float)size +{ + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + + // Do a simple case insensitive search for a matching font family. + // NSFontManager requires exact name matches. + // This addresses the problem of matching arial to Arial, etc., but perhaps not all the issues. + NSEnumerator *e = [[fontManager availableFontFamilies] objectEnumerator]; + NSString *availableFamily; + while ((availableFamily = [e nextObject])) { + if ([desiredFamily caseInsensitiveCompare:availableFamily] == NSOrderedSame) + break; + } + + if (!availableFamily) { + // Match by PostScript name. + NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnumerator]; + NSString *availableFont; + NSFont *nameMatchedFont = nil; + NSFontTraitMask desiredTraitsForNameMatch = desiredTraits | (desiredWeight >= 7 ? NSBoldFontMask : 0); + while ((availableFont = [availableFonts nextObject])) { + if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrderedSame) { + nameMatchedFont = [NSFont fontWithName:availableFont size:size]; + + // Special case Osaka-Mono. According to <rdar://problem/3999467>, we need to + // treat Osaka-Mono as fixed pitch. + if ([desiredFamily caseInsensitiveCompare:@"Osaka-Mono"] == NSOrderedSame && desiredTraitsForNameMatch == 0) + return nameMatchedFont; + + NSFontTraitMask traits = [fontManager traitsOfFont:nameMatchedFont]; + if ((traits & desiredTraitsForNameMatch) == desiredTraitsForNameMatch) + return [fontManager convertFont:nameMatchedFont toHaveTrait:desiredTraitsForNameMatch]; + + availableFamily = [nameMatchedFont familyName]; + break; + } + } + } + + // Found a family, now figure out what weight and traits to use. + BOOL choseFont = false; + int chosenWeight = 0; + NSFontTraitMask chosenTraits = 0; + NSString *chosenFullName = 0; + + NSArray *fonts = [fontManager availableMembersOfFontFamily:availableFamily]; + unsigned n = [fonts count]; + unsigned i; + for (i = 0; i < n; i++) { + NSArray *fontInfo = [fonts objectAtIndex:i]; + + // Array indices must be hard coded because of lame AppKit API. + NSString *fontFullName = [fontInfo objectAtIndex:0]; + NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue]; + fixUpWeight(fontWeight, fontFullName); + + NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValue]; + + BOOL newWinner; + if (!choseFont) + newWinner = acceptableChoice(desiredTraits, fontTraits); + else + newWinner = betterChoice(desiredTraits, desiredWeight, chosenTraits, chosenWeight, fontTraits, fontWeight); + + if (newWinner) { + choseFont = YES; + chosenWeight = fontWeight; + chosenTraits = fontTraits; + chosenFullName = fontFullName; + + if (chosenWeight == desiredWeight && (chosenTraits & IMPORTANT_FONT_TRAITS) == (desiredTraits & IMPORTANT_FONT_TRAITS)) + break; + } + } + + if (!choseFont) + return nil; + + NSFont *font = [NSFont fontWithName:chosenFullName size:size]; + + if (!font) + return nil; + + NSFontTraitMask actualTraits = 0; + if (desiredTraits & NSFontItalicTrait) + actualTraits = [fontManager traitsOfFont:font]; + int actualWeight = [fontManager weightOfFont:font]; + + bool syntheticBold = desiredWeight >= 7 && actualWeight < 7; + bool syntheticOblique = (desiredTraits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait); + + // There are some malformed fonts that will be correctly returned by -fontWithFamily:traits:weight:size: as a match for a particular trait, + // though -[NSFontManager traitsOfFont:] incorrectly claims the font does not have the specified trait. This could result in applying + // synthetic bold on top of an already-bold font, as reported in <http://bugs.webkit.org/show_bug.cgi?id=6146>. To work around this + // problem, if we got an apparent exact match, but the requested traits aren't present in the matched font, we'll try to get a font from + // the same family without those traits (to apply the synthetic traits to later). + NSFontTraitMask nonSyntheticTraits = desiredTraits; + + if (syntheticBold) + nonSyntheticTraits &= ~NSBoldFontMask; + + if (syntheticOblique) + nonSyntheticTraits &= ~NSItalicFontMask; + + if (nonSyntheticTraits != desiredTraits) { + NSFont *fontWithoutSyntheticTraits = [fontManager fontWithFamily:availableFamily traits:nonSyntheticTraits weight:chosenWeight size:size]; + if (fontWithoutSyntheticTraits) + font = fontWithoutSyntheticTraits; + } + + return font; +} + ++ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits weight:(int)desiredWeight size:(float)size +{ +#ifndef BUILDING_ON_TIGER + NSFont *font = [self internalFontWithFamily:desiredFamily traits:desiredTraits weight:desiredWeight size:size]; + if (font) + return font; + + // Auto activate the font before looking for it a second time. + // Ignore the result because we want to use our own algorithm to actually find the font. + [NSFont fontWithName:desiredFamily size:size]; +#endif + + return [self internalFontWithFamily:desiredFamily traits:desiredTraits weight:desiredWeight size:size]; +} + ++ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits size:(float)size +{ + int desiredWeight = (desiredTraits & NSBoldFontMask) ? 9 : 5; + return [self fontWithFamily:desiredFamily traits:desiredTraits weight:desiredWeight size:size]; +} + +@end diff --git a/Source/WebCore/platform/mac/WheelEventMac.mm b/Source/WebCore/platform/mac/WheelEventMac.mm new file mode 100644 index 0000000..d9663b9 --- /dev/null +++ b/Source/WebCore/platform/mac/WheelEventMac.mm @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2004, 2006, 2010 Apple Computer, 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. + */ + +#import "config.h" +#import "PlatformWheelEvent.h" + +#import "PlatformMouseEvent.h" +#import "Scrollbar.h" +#import "WebCoreSystemInterface.h" + +namespace WebCore { + +PlatformWheelEvent::PlatformWheelEvent(NSEvent* event, NSView *windowView) + : m_position(pointForEvent(event, windowView)) + , m_globalPosition(globalPointForEvent(event)) + , m_granularity(ScrollByPixelWheelEvent) + , m_isAccepted(false) + , m_shiftKey([event modifierFlags] & NSShiftKeyMask) + , m_ctrlKey([event modifierFlags] & NSControlKeyMask) + , m_altKey([event modifierFlags] & NSAlternateKeyMask) + , m_metaKey([event modifierFlags] & NSCommandKeyMask) +{ + BOOL continuous; + + wkGetWheelEventDeltas(event, &m_deltaX, &m_deltaY, &continuous); + if (continuous) { + m_wheelTicksX = m_deltaX / static_cast<float>(Scrollbar::pixelsPerLineStep()); + m_wheelTicksY = m_deltaY / static_cast<float>(Scrollbar::pixelsPerLineStep()); + } else { + m_wheelTicksX = m_deltaX; + m_wheelTicksY = m_deltaY; + m_deltaX *= static_cast<float>(Scrollbar::pixelsPerLineStep()); + m_deltaY *= static_cast<float>(Scrollbar::pixelsPerLineStep()); + } +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/WidgetMac.mm b/Source/WebCore/platform/mac/WidgetMac.mm new file mode 100644 index 0000000..e8bb81d --- /dev/null +++ b/Source/WebCore/platform/mac/WidgetMac.mm @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "Widget.h" + +#ifdef BUILDING_ON_TIGER +#import "AutodrainedPool.h" +#endif + +#import "BlockExceptions.h" +#import "Chrome.h" +#import "Cursor.h" +#import "Document.h" +#import "Font.h" +#import "Frame.h" +#import "GraphicsContext.h" +#import "NotImplemented.h" +#import "Page.h" +#import "PlatformMouseEvent.h" +#import "ScrollView.h" +#import "WebCoreFrameView.h" +#import "WebCoreView.h" +#import <wtf/RetainPtr.h> + +@interface NSWindow (WebWindowDetails) +- (BOOL)_needsToResetDragMargins; +- (void)_setNeedsToResetDragMargins:(BOOL)needs; +@end + +@interface NSView (WebSetSelectedMethods) +- (void)setIsSelected:(BOOL)isSelected; +- (void)webPlugInSetIsSelected:(BOOL)isSelected; +@end + +@interface NSView (Widget) +- (void)visibleRectDidChange; +@end + +namespace WebCore { + +class WidgetPrivate { +public: + WidgetPrivate() + : previousVisibleRect(NSZeroRect) + { + } + + bool mustStayInWindow; + bool removeFromSuperviewSoon; + NSRect previousVisibleRect; +}; + +static void safeRemoveFromSuperview(NSView *view) +{ + // If the the view is the first responder, then set the window's first responder to nil so + // we don't leave the window pointing to a view that's no longer in it. + NSWindow *window = [view window]; + NSResponder *firstResponder = [window firstResponder]; + if ([firstResponder isKindOfClass:[NSView class]] && [(NSView *)firstResponder isDescendantOf:view]) + [window makeFirstResponder:nil]; + + // Suppress the resetting of drag margins since we know we can't affect them. + BOOL resetDragMargins = [window _needsToResetDragMargins]; + [window _setNeedsToResetDragMargins:NO]; + [view removeFromSuperview]; + [window _setNeedsToResetDragMargins:resetDragMargins]; +} + +Widget::Widget(NSView *view) + : m_data(new WidgetPrivate) +{ + init(view); + m_data->mustStayInWindow = false; + m_data->removeFromSuperviewSoon = false; +} + +Widget::~Widget() +{ + delete m_data; +} + +// FIXME: Should move this to Chrome; bad layering that this knows about Frame. +void Widget::setFocus(bool focused) +{ + if (!focused) + return; + + Frame* frame = Frame::frameForWidget(this); + if (!frame) + return; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSView *view = [platformWidget() _webcore_effectiveFirstResponder]; + if (Page* page = frame->page()) + page->chrome()->focusNSView(view); + + END_BLOCK_OBJC_EXCEPTIONS; +} + +void Widget::setCursor(const Cursor& cursor) +{ + ScrollView* view = root(); + if (!view) + return; + view->hostWindow()->setCursor(cursor); +} + +void Widget::show() +{ + if (isSelfVisible()) + return; + + setSelfVisible(true); + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [getOuterView() setHidden:NO]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +void Widget::hide() +{ + if (!isSelfVisible()) + return; + + setSelfVisible(false); + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [getOuterView() setHidden:YES]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +IntRect Widget::frameRect() const +{ + if (!platformWidget()) + return m_frame; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return enclosingIntRect([getOuterView() frame]); + END_BLOCK_OBJC_EXCEPTIONS; + + return m_frame; +} + +void Widget::setFrameRect(const IntRect& rect) +{ + m_frame = rect; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSView *v = getOuterView(); + if (!v) + return; + + NSRect visibleRect = [v visibleRect]; + NSRect f = rect; + if (!NSEqualRects(f, [v frame])) { + [v setFrame:f]; + [v setNeedsDisplay:NO]; + } else if (!NSEqualRects(visibleRect, m_data->previousVisibleRect) && [v respondsToSelector:@selector(visibleRectDidChange)]) + [v visibleRectDidChange]; + + m_data->previousVisibleRect = visibleRect; + END_BLOCK_OBJC_EXCEPTIONS; +} + +NSView* Widget::getOuterView() const +{ + NSView* view = platformWidget(); + + // If this widget's view is a WebCoreFrameScrollView then we + // resize its containing view, a WebFrameView. + if ([view conformsToProtocol:@protocol(WebCoreFrameScrollView)]) { + view = [view superview]; + ASSERT(view); + } + + return view; +} + +void Widget::paint(GraphicsContext* p, const IntRect& r) +{ + if (p->paintingDisabled()) + return; + NSView *view = getOuterView(); + NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; + if (currentContext == [[view window] graphicsContext] || ![currentContext isDrawingToScreen]) { + // This is the common case of drawing into a window or printing. + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]]]; + END_BLOCK_OBJC_EXCEPTIONS; + } else { + // This is the case of drawing into a bitmap context other than a window backing store. It gets hit beneath + // -cacheDisplayInRect:toBitmapImageRep:, and when painting into compositing layers. + + // Transparent subframes are in fact implemented with scroll views that return YES from -drawsBackground (whenever the WebView + // itself is in drawsBackground mode). In the normal drawing code path, the scroll views are never asked to draw the background, + // so this is not an issue, but in this code path they are, so the following code temporarily turns background drwaing off. + NSView *innerView = platformWidget(); + NSScrollView *scrollView = 0; + if ([innerView conformsToProtocol:@protocol(WebCoreFrameScrollView)]) { + ASSERT([innerView isKindOfClass:[NSScrollView class]]); + NSScrollView *scrollView = static_cast<NSScrollView *>(innerView); + // -copiesOnScroll will return NO whenever the content view is not fully opaque. + if ([scrollView drawsBackground] && ![[scrollView contentView] copiesOnScroll]) + [scrollView setDrawsBackground:NO]; + else + scrollView = 0; + } + + CGContextRef cgContext = p->platformContext(); + ASSERT(cgContext == [currentContext graphicsPort]); + CGContextSaveGState(cgContext); + + NSRect viewFrame = [view frame]; + NSRect viewBounds = [view bounds]; + // Set up the translation and (flipped) orientation of the graphics context. In normal drawing, AppKit does it as it descends down + // the view hierarchy. + CGContextTranslateCTM(cgContext, viewFrame.origin.x - viewBounds.origin.x, viewFrame.origin.y + viewFrame.size.height + viewBounds.origin.y); + CGContextScaleCTM(cgContext, 1, -1); + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + { +#ifdef BUILDING_ON_TIGER + AutodrainedPool pool; +#endif + NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]; + [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]] inContext:nsContext]; + } + END_BLOCK_OBJC_EXCEPTIONS; + + CGContextRestoreGState(cgContext); + + if (scrollView) + [scrollView setDrawsBackground:YES]; + } +} + +void Widget::setIsSelected(bool isSelected) +{ + NSView *view = platformWidget(); + BEGIN_BLOCK_OBJC_EXCEPTIONS; + if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)]) + [view webPlugInSetIsSelected:isSelected]; + else if ([view respondsToSelector:@selector(setIsSelected:)]) + [view setIsSelected:isSelected]; + END_BLOCK_OBJC_EXCEPTIONS; +} + +void Widget::removeFromSuperview() +{ + if (m_data->mustStayInWindow) + m_data->removeFromSuperviewSoon = true; + else { + m_data->removeFromSuperviewSoon = false; + BEGIN_BLOCK_OBJC_EXCEPTIONS; + safeRemoveFromSuperview(getOuterView()); + END_BLOCK_OBJC_EXCEPTIONS; + } +} + +void Widget::beforeMouseDown(NSView *unusedView, Widget* widget) +{ + if (widget) { + ASSERT_UNUSED(unusedView, unusedView == widget->getOuterView()); + ASSERT(!widget->m_data->mustStayInWindow); + widget->m_data->mustStayInWindow = true; + } +} + +void Widget::afterMouseDown(NSView *view, Widget* widget) +{ + if (!widget) { + BEGIN_BLOCK_OBJC_EXCEPTIONS; + safeRemoveFromSuperview(view); + END_BLOCK_OBJC_EXCEPTIONS; + } else { + ASSERT(widget->m_data->mustStayInWindow); + widget->m_data->mustStayInWindow = false; + if (widget->m_data->removeFromSuperviewSoon) + widget->removeFromSuperview(); + } +} + +// These are here to deal with flipped coords on Mac. +IntRect Widget::convertFromRootToContainingWindow(const Widget* rootWidget, const IntRect& rect) +{ + if (!rootWidget->platformWidget()) + return rect; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return enclosingIntRect([rootWidget->platformWidget() convertRect:rect toView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + + return rect; +} + +IntRect Widget::convertFromContainingWindowToRoot(const Widget* rootWidget, const IntRect& rect) +{ + if (!rootWidget->platformWidget()) + return rect; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return enclosingIntRect([rootWidget->platformWidget() convertRect:rect fromView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + + return rect; +} + +IntPoint Widget::convertFromRootToContainingWindow(const Widget* rootWidget, const IntPoint& point) +{ + if (!rootWidget->platformWidget()) + return point; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return IntPoint([rootWidget->platformWidget() convertPoint:point toView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + return point; +} + +IntPoint Widget::convertFromContainingWindowToRoot(const Widget* rootWidget, const IntPoint& point) +{ + if (!rootWidget->platformWidget()) + return point; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return IntPoint([rootWidget->platformWidget() convertPoint:point fromView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + + return point; +} + +NSView *Widget::platformWidget() const +{ + return m_widget.get(); +} + +void Widget::setPlatformWidget(NSView *widget) +{ + if (widget == m_widget) + return; + + m_widget = widget; + m_data->previousVisibleRect = NSZeroRect; +} + +} // namespace WebCore |