15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Many of these functions are based on those found in 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webkit/port/platform/PasteboardWin.cpp 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/clipboard.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shellapi.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/shared_memory.h" 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/safe_numerics.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/utf_offset_string_conversions.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/win/message_window.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_gdi_object.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_hdc.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/clipboard_util_win.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/custom_data_helper.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A scoper to manage acquiring and automatically releasing the clipboard. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedClipboard { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard() : opened_(false) { } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ScopedClipboard() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opened_) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Acquire(HWND owner) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxAttemptsToOpenClipboard = 5; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opened_) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt to open the clipboard, which will acquire the Windows clipboard 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lock. This may fail if another process currently holds this lock. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're willing to try a few times in the hopes of acquiring it. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This turns out to be an issue when using remote desktop because the 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rdpclip.exe process likes to read what we've written to the clipboard and 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // send it to the RDP client. If we open and close the clipboard in quick 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // succession, we might be trying to open it while rdpclip.exe has it open, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See Bug 815425. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In fact, we believe we'll only spin this loop over remote desktop. In 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // normal situations, the user is initiating clipboard operations and there 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shouldn't be contention. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int attempts = 0; attempts < kMaxAttemptsToOpenClipboard; ++attempts) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we didn't manage to open the clipboard, sleep a bit and be hopeful. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (attempts != 0) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Sleep(5); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::OpenClipboard(owner)) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opened_ = true; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We failed to acquire the clipboard. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Release() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opened_) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseClipboard(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opened_ = false; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool opened_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ClipboardOwnerWndProc(UINT message, 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WPARAM wparam, 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LPARAM lparam, 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LRESULT* result) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (message) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_RENDERFORMAT: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This message comes when SetClipboardData was sent a null data handle 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and now it's come time to put the data on the clipboard. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We always set data, so there isn't a need to actually do anything here. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_RENDERALLFORMATS: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This message comes when SetClipboardData was sent a null data handle 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and now this application is about to quit, so it must put data on 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the clipboard before it exits. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We always set data, so there isn't a need to actually do anything here. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_DRAWCLIPBOARD: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_DESTROY: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_CHANGECBCHAIN: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *result = 0; 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename charT> 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL data = 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT))); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charT* raw_data = static_cast<charT*>(::GlobalLock(data)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(raw_data, str.data(), str.size() * sizeof(charT)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[str.size()] = '\0'; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BitmapHasInvalidPremultipliedColors(const SkBitmap& bitmap) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < bitmap.width(); ++x) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < bitmap.height(); ++y) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t pixel = *bitmap.getAddr32(x, y); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SkColorGetR(pixel) > SkColorGetA(pixel) || 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColorGetG(pixel) > SkColorGetA(pixel) || 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColorGetB(pixel) > SkColorGetA(pixel)) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MakeBitmapOpaque(const SkBitmap& bitmap) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < bitmap.width(); ++x) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < bitmap.height(); ++y) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Clipboard::FormatType::FormatType() : data_() {} 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Clipboard::FormatType::FormatType(UINT native_format) : data_() { 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There's no good way to actually initialize this in the constructor in 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // C++03. 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.cfFormat = native_format; 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.dwAspect = DVASPECT_CONTENT; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.lindex = -1; 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.tymed = TYMED_HGLOBAL; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Clipboard::FormatType::FormatType(UINT native_format, LONG index) : data_() { 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // There's no good way to actually initialize this in the constructor in 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // C++03. 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.cfFormat = native_format; 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.dwAspect = DVASPECT_CONTENT; 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.lindex = index; 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data_.tymed = TYMED_HGLOBAL; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::~FormatType() { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Clipboard::FormatType::Serialize() const { 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return base::IntToString(data_.cfFormat); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType Clipboard::FormatType::Deserialize( 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& serialization) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int clipboard_format = -1; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt(serialization, &clipboard_format)) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FormatType(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FormatType(clipboard_format); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool Clipboard::FormatType::operator<(const FormatType& other) const { 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ToUINT() < other.ToUINT(); 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochClipboard::Clipboard() { 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI) 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch clipboard_owner_.reset(new base::win::MessageWindow()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::~Clipboard() { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::EmptyClipboard(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ObjectMap::const_iterator iter = objects.begin(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != objects.end(); ++iter) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchObject(static_cast<ObjectType>(iter->first), iter->second); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteText(const char* text_data, size_t text_len) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF8ToUTF16(text_data, text_len, &text); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL glob = CreateGlobalData(text); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(CF_UNICODETEXT, glob); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteHTML(const char* markup_data, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t markup_len, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t url_len) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string markup(markup_data, markup_len); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_len > 0) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.assign(url_data, url_len); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL glob = CreateGlobalData(html_fragment); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteToClipboard(Clipboard::GetHtmlFormatType().ToUINT(), glob); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteData(GetRtfFormatType(), rtf_data, data_len); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteBookmark(const char* title_data, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t title_len, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t url_len) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string bookmark(title_data, title_len); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark.append(1, L'\n'); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark.append(url_data, url_len); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 wide_bookmark = UTF8ToWide(bookmark); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL glob = CreateGlobalData(wide_bookmark); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WriteToClipboard(GetUrlWFormatType().ToUINT(), glob); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteWebSmartPaste() { 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(clipboard_owner_->hwnd() != NULL); 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ::SetClipboardData(GetWebKitSmartPasteFormatType().ToUINT(), NULL); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Clipboard::WriteBitmap(const SkBitmap& bitmap) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC dc = ::GetDC(NULL); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This doesn't actually cost us a memcpy when the bitmap comes from the 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // renderer as we load it into the bitmap using setPixels which just sets a 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer. Someone has to memcpy it into GDI, it might as well be us here. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): share data in gfx/bitmap_header.cc somehow 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BITMAPINFO bm_info = {0}; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bm_info.bmiHeader.biWidth = bitmap.width(); 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bm_info.bmiHeader.biHeight = -bitmap.height(); // sets vertical orientation 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biPlanes = 1; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biBitCount = 32; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biCompression = BI_RGB; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ::CreateDIBSection allocates memory for us to copy our bitmap into. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unfortunately, we can't write the created bitmap to the clipboard, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *bits; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP source_hbitmap = 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bits && source_hbitmap) { 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SkAutoLockPixels bitmap_lock(bitmap); 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Copy the bitmap out of shared memory and into GDI 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) memcpy(bits, bitmap.getPixels(), bitmap.getSize()); 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we have an HBITMAP, we can write it to the clipboard 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WriteBitmapFromHandle(source_hbitmap, 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Size(bitmap.width(), bitmap.height())); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(source_hbitmap); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ReleaseDC(NULL, dc); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We would like to just call ::SetClipboardData on the source_hbitmap, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but that bitmap might not be of a sort we can write to the clipboard. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For this reason, we create a new bitmap, copy the bits over, and then 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // write that to the clipboard. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC dc = ::GetDC(NULL); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC compatible_dc = ::CreateCompatibleDC(NULL); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC source_dc = ::CreateCompatibleDC(NULL); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the HBITMAP we will eventually write to the clipboard 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP hbitmap = ::CreateCompatibleBitmap(dc, size.width(), size.height()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hbitmap) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Failed to create the bitmap 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(compatible_dc); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(source_dc); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ReleaseDC(NULL, dc); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP old_hbitmap = (HBITMAP)SelectObject(compatible_dc, hbitmap); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP old_source = (HBITMAP)SelectObject(source_dc, source_hbitmap); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we need to blend it into an HBITMAP we can place on the clipboard 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GdiAlphaBlend(compatible_dc, 0, 0, size.width(), size.height(), 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_dc, 0, 0, size.width(), size.height(), bf); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up all the handles we just opened 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SelectObject(compatible_dc, old_hbitmap); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SelectObject(source_dc, old_source); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(old_hbitmap); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(old_source); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(compatible_dc); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(source_dc); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ReleaseDC(NULL, dc); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(CF_BITMAP, hbitmap); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteData(const FormatType& format, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data_data, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t data_len) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL hdata = ::GlobalAlloc(GMEM_MOVEABLE, data_len); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hdata) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data = static_cast<char*>(::GlobalLock(hdata)); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(data, data_data, data_len); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(format.ToUINT(), hdata); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(clipboard_owner_->hwnd() != NULL); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handle && !::SetClipboardData(format, handle)) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreeData(format, handle); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)uint64 Clipboard::GetSequenceNumber(ClipboardType type) { 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::GetClipboardSequenceNumber(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, 3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ClipboardType type) const { 3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::IsClipboardFormatAvailable(format.ToUINT()) != FALSE; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::Clear(ClipboardType type) { 3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::EmptyClipboard(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadAvailableTypes(ClipboardType type, 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<string16>* types, 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* contains_filenames) const { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!types || !contains_filenames) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->clear(); 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (::IsClipboardFormatAvailable(GetPlainTextFormatType().ToUINT())) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeText)); 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (::IsClipboardFormatAvailable(GetHtmlFormatType().ToUINT())) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeHTML)); 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (::IsClipboardFormatAvailable(GetRtfFormatType().ToUINT())) 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeRTF)); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsClipboardFormatAvailable(CF_DIB)) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypePNG)); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contains_filenames = false; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HANDLE hdata = ::GetClipboardData(GetWebCustomDataFormatType().ToUINT()); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hdata) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadCustomDataTypes(::GlobalLock(hdata), ::GlobalSize(hdata), types); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(hdata); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadText(ClipboardType type, string16* result) const { 4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->clear(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE data = ::GetClipboardData(CF_UNICODETEXT); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(static_cast<const char16*>(::GlobalLock(data))); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const { 4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->clear(); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE data = ::GetClipboardData(CF_TEXT); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(static_cast<const char*>(::GlobalLock(data))); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadHTML(ClipboardType type, 4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) string16* markup, 4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string* src_url, 4764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32* fragment_start, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* fragment_end) const { 4784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markup->clear(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(dcheng): Remove these checks, I don't think they should be optional. 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(src_url); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src_url) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_url->clear(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_start = 0; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_end = 0; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HANDLE data = ::GetClipboardData(GetHtmlFormatType().ToUINT()); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cf_html(static_cast<const char*>(::GlobalLock(data))); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t html_start = std::string::npos; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_index = std::string::npos; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t end_index = std::string::npos; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClipboardUtil::CFHtmlExtractMetadata(cf_html, src_url, &html_start, 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &start_index, &end_index); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This might happen if the contents of the clipboard changed and CF_HTML is 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no longer available. 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_index == std::string::npos || 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_index == std::string::npos || 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) html_start == std::string::npos) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (start_index < html_start || end_index < start_index) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<size_t> offsets; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets.push_back(start_index - html_start); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets.push_back(end_index - html_start); 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) markup->assign(base::UTF8ToUTF16AndAdjustOffsets(cf_html.data() + html_start, 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &offsets)); 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *fragment_start = base::checked_numeric_cast<uint32>(offsets[0]); 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *fragment_end = base::checked_numeric_cast<uint32>(offsets[1]); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadRTF(ClipboardType type, std::string* result) const { 5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadData(GetRtfFormatType(), result); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SkBitmap Clipboard::ReadImage(ClipboardType type) const { 5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SkBitmap(); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We use a DIB rather than a DDB here since ::GetObject() with the 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HBITMAP returned from ::GetClipboardData(CF_BITMAP) always reports a color 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // depth of 32bpp. 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BITMAPINFO* bitmap = static_cast<BITMAPINFO*>(::GetClipboardData(CF_DIB)); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bitmap) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SkBitmap(); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int color_table_length = 0; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (bitmap->bmiHeader.biBitCount) { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_table_length = bitmap->bmiHeader.biClrUsed 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? bitmap->bmiHeader.biClrUsed 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : 1 << bitmap->bmiHeader.biBitCount; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 16: 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 32: 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bitmap->bmiHeader.biCompression == BI_BITFIELDS) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_table_length = 3; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 24: 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* bitmap_bits = reinterpret_cast<const char*>(bitmap) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + bitmap->bmiHeader.biSize + color_table_length * sizeof(RGBQUAD); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Canvas canvas(gfx::Size(bitmap->bmiHeader.biWidth, 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->bmiHeader.biHeight), 56968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1.0f, 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC dc = scoped_platform_paint.GetPlatformSurface(); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetDIBitsToDevice(dc, 0, 0, bitmap->bmiHeader.biWidth, 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->bmiHeader.biHeight, 0, 0, 0, 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->bmiHeader.biHeight, bitmap_bits, bitmap, 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIB_RGB_COLORS); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows doesn't really handle alpha channels well in many situations. When 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the source image is < 32 bpp, we force the bitmap to be opaque. When the 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // source image is 32 bpp, the alpha channel might still contain garbage data. 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since Windows uses premultiplied alpha, we scan for instances where 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (R, G, B) > A. If there are any invalid premultiplied colors in the image, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we assume the alpha channel contains garbage and force the bitmap to be 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opaque as well. Note that this heuristic will fail on a transparent bitmap 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // containing only black pixels... 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& device_bitmap = 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas.sk_canvas()->getDevice()->accessBitmap(true); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkAutoLockPixels lock(device_bitmap); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_invalid_alpha_channel = bitmap->bmiHeader.biBitCount < 32 || 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitmapHasInvalidPremultipliedColors(device_bitmap); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_invalid_alpha_channel) { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeBitmapOpaque(device_bitmap); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas.ExtractImageRep().sk_bitmap(); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadCustomData(ClipboardType clipboard_type, 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& type, 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* result) const { 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(clipboard_type, CLIPBOARD_TYPE_COPY_PASTE); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HANDLE hdata = ::GetClipboardData(GetWebCustomDataFormatType().ToUINT()); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hdata) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadCustomDataForType(::GlobalLock(hdata), ::GlobalSize(hdata), type, result); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(hdata); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadBookmark(string16* title, std::string* url) const { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (title) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title->clear(); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url->clear(); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) HANDLE data = ::GetClipboardData(GetUrlWFormatType().ToUINT()); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 bookmark(static_cast<const char16*>(::GlobalLock(data))); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseBookmarkClipboardFormat(bookmark, title, url); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadData(const FormatType& format, std::string* result) const { 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE data = ::GetClipboardData(format.ToUINT()); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(static_cast<const char*>(::GlobalLock(data)), 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalSize(data)); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ParseBookmarkClipboardFormat(const string16& bookmark, 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* title, 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* url) { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kDelim = ASCIIToUTF16("\r\n"); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t title_end = bookmark.find_first_of(kDelim); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (title) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title->assign(bookmark.substr(0, title_end)); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url) { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t url_start = bookmark.find_first_not_of(kDelim, title_end); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_start != string16::npos) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *url = UTF16ToUTF8(bookmark.substr(url_start, string16::npos)); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType Clipboard::GetFormatType( 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& format_string) { 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FormatType( 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::RegisterClipboardFormat(ASCIIToWide(format_string).c_str())); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetUrlFormatType() { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 68790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(CFSTR_INETURLA))); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetUrlWFormatType() { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 69490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(CFSTR_INETURLW))); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetMozUrlFormatType() { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 70190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(L"text/x-moz-url"))); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() { 70790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (CF_TEXT)); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() { 71390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (CF_UNICODETEXT)); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFilenameFormatType() { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 72090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(CFSTR_FILENAMEA))); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 72790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(CFSTR_FILENAMEW))); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MS HTML Format 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetHtmlFormatType() { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 73590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(L"HTML Format"))); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MS RTF Format 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetRtfFormatType() { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 74390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(L"Rich Text Format"))); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetBitmapFormatType() { 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (CF_BITMAP)); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Firefox text/html 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetTextHtmlFormatType() { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 75790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(L"text/html"))); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetCFHDropFormatType() { 76390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (CF_HDROP)); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFileDescriptorFormatType() { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 77090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR))); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFileContentZeroFormatType() { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(CFSTR_FILECONTENTS), 0)); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetIDListFormatType() { 7837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FormatType, type, (::RegisterClipboardFormat(CFSTR_SHELLIDLIST))); 7857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return type; 7867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 7877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (::RegisterClipboardFormat(L"WebKit Smart Paste Format"))); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { 79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(dcheng): This name is temporary. See http://crbug.com/106449. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 80390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (::RegisterClipboardFormat(L"Chromium Web Custom MIME Data Format"))); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 81290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (::RegisterClipboardFormat(L"Chromium Pepper MIME Data Format"))); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::FreeData(unsigned int format, HANDLE data) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format == CF_BITMAP) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(static_cast<HBITMAP>(data)); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalFree(data); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HWND Clipboard::GetClipboardWindow() const { 825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!clipboard_owner_) 826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return NULL; 827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (clipboard_owner_->hwnd() == NULL) 829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch clipboard_owner_->Create(base::Bind(&ClipboardOwnerWndProc)); 830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return clipboard_owner_->hwnd(); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 835