1/* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "WebDragClient.h" 28 29#if ENABLE(DRAG_SUPPORT) 30 31#import "PasteboardTypes.h" 32#import "ShareableBitmap.h" 33#import "WebCoreArgumentCoders.h" 34#import "WebPage.h" 35#import "WebPageProxyMessages.h" 36#import <WebCore/CachedImage.h> 37#import <WebCore/DOMElementInternal.h> 38#import <WebCore/DOMPrivate.h> 39#import <WebCore/DragController.h> 40#import <WebCore/Frame.h> 41#import <WebCore/FrameView.h> 42#import <WebCore/GraphicsContext.h> 43#import <WebCore/LegacyWebArchive.h> 44#import <WebCore/Page.h> 45#import <WebCore/RenderImage.h> 46#import <WebCore/ResourceHandle.h> 47#import <WebCore/StringTruncator.h> 48#import <WebKit/WebArchive.h> 49#import <WebKit/WebKitNSStringExtras.h> 50#import <WebKit/WebNSFileManagerExtras.h> 51#import <WebKit/WebNSPasteboardExtras.h> 52#import <WebKit/WebNSURLExtras.h> 53#import <WebKitSystemInterface.h> 54#import <wtf/StdLibExtras.h> 55 56using namespace WebCore; 57using namespace WebKit; 58 59namespace WebKit { 60 61static PassRefPtr<ShareableBitmap> convertImageToBitmap(NSImage *image, const IntSize& size) 62{ 63 RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(size, ShareableBitmap::SupportsAlpha); 64 if (!bitmap) 65 return nullptr; 66 67 OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); 68 69 RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext]; 70 71 [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:graphicsContext->platformContext() flipped:YES]]; 72 [image drawInRect:NSMakeRect(0, 0, bitmap->size().width(), bitmap->size().height()) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil]; 73 74 [NSGraphicsContext setCurrentContext:savedContext.get()]; 75 76 return bitmap.release(); 77} 78 79void WebDragClient::startDrag(RetainPtr<NSImage> image, const IntPoint& point, const IntPoint&, Clipboard*, Frame* frame, bool linkDrag) 80{ 81 IntSize bitmapSize([image.get() size]); 82 bitmapSize.scale(frame->page()->deviceScaleFactor()); 83 RefPtr<ShareableBitmap> bitmap = convertImageToBitmap(image.get(), bitmapSize); 84 ShareableBitmap::Handle handle; 85 if (!bitmap || !bitmap->createHandle(handle)) 86 return; 87 88 // FIXME: Seems this message should be named StartDrag, not SetDragImage. 89 m_page->send(Messages::WebPageProxy::SetDragImage(frame->view()->contentsToWindow(point), handle, linkDrag)); 90} 91 92static WebCore::CachedImage* cachedImage(Element* element) 93{ 94 RenderObject* renderer = element->renderer(); 95 if (!renderer) 96 return 0; 97 if (!renderer->isRenderImage()) 98 return 0; 99 WebCore::CachedImage* image = toRenderImage(renderer)->cachedImage(); 100 if (!image || image->errorOccurred()) 101 return 0; 102 return image; 103} 104 105void WebDragClient::declareAndWriteDragImage(const String& pasteboardName, DOMElement *element, NSURL *URL, NSString *title, WebCore::Frame*) 106{ 107 ASSERT(element); 108 ASSERT(pasteboardName == String(NSDragPboard)); 109 110 Element* coreElement = core(element); 111 112 WebCore::CachedImage* image = cachedImage(coreElement); 113 114 NSString *extension = @""; 115 if (image) { 116 extension = image->image()->filenameExtension(); 117 if (![extension length]) 118 return; 119 } 120 121 if (![title length]) { 122 title = [[URL path] lastPathComponent]; 123 if (![title length]) 124 title = [URL _web_userVisibleString]; 125 } 126 127 RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(coreElement); 128 129 NSURLResponse *response = image->response().nsURLResponse(); 130 131 RefPtr<SharedBuffer> imageBuffer = image->image()->data(); 132 size_t imageSize = imageBuffer->size(); 133 SharedMemory::Handle imageHandle; 134 135 RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(imageBuffer->size()); 136 memcpy(sharedMemoryBuffer->data(), imageBuffer->data(), imageSize); 137 sharedMemoryBuffer->createHandle(imageHandle, SharedMemory::ReadOnly); 138 139 RetainPtr<CFDataRef> data = archive ? archive->rawDataRepresentation() : 0; 140 SharedMemory::Handle archiveHandle; 141 size_t archiveSize = 0; 142 if (data) { 143 RefPtr<SharedBuffer> buffer = SharedBuffer::wrapNSData((NSData *)data.get()); 144 RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(buffer->size()); 145 archiveSize = buffer->size(); 146 memcpy(sharedMemoryBuffer->data(), buffer->data(), archiveSize); 147 sharedMemoryBuffer->createHandle(archiveHandle, SharedMemory::ReadOnly); 148 } 149 m_page->send(Messages::WebPageProxy::SetPromisedData(pasteboardName, imageHandle, imageSize, String([response suggestedFilename]), String(extension), String(title), String([[response URL] absoluteString]), String([URL _web_userVisibleString]), archiveHandle, archiveSize)); 150} 151 152} // namespace WebKit 153 154#endif // ENABLE(DRAG_SUPPORT) 155