clipboard_win.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_path.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/shared_memory.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_number_conversions.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_offset_string_conversions.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_gdi_object.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_hdc.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/wrapped_window_proc.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/clipboard_util_win.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/custom_data_helper.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A scoper to manage acquiring and automatically releasing the clipboard. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedClipboard { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard() : opened_(false) { } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ScopedClipboard() { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opened_) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Acquire(HWND owner) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxAttemptsToOpenClipboard = 5; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opened_) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt to open the clipboard, which will acquire the Windows clipboard 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lock. This may fail if another process currently holds this lock. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're willing to try a few times in the hopes of acquiring it. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This turns out to be an issue when using remote desktop because the 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rdpclip.exe process likes to read what we've written to the clipboard and 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // send it to the RDP client. If we open and close the clipboard in quick 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // succession, we might be trying to open it while rdpclip.exe has it open, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See Bug 815425. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In fact, we believe we'll only spin this loop over remote desktop. In 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // normal situations, the user is initiating clipboard operations and there 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shouldn't be contention. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int attempts = 0; attempts < kMaxAttemptsToOpenClipboard; ++attempts) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we didn't manage to open the clipboard, sleep a bit and be hopeful. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (attempts != 0) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::Sleep(5); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::OpenClipboard(owner)) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opened_ = true; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We failed to acquire the clipboard. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Release() { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opened_) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseClipboard(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opened_ = false; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool opened_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LRESULT CALLBACK ClipboardOwnerWndProc(HWND hwnd, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT message, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WPARAM wparam, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LPARAM lparam) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LRESULT lresult = 0; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 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: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lresult = DefWindowProc(hwnd, message, wparam, lparam); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return lresult; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename charT> 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL data = 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT))); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) charT* raw_data = static_cast<charT*>(::GlobalLock(data)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(raw_data, str.data(), str.size() * sizeof(charT)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raw_data[str.size()] = '\0'; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BitmapHasInvalidPremultipliedColors(const SkBitmap& bitmap) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < bitmap.width(); ++x) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < bitmap.height(); ++y) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t pixel = *bitmap.getAddr32(x, y); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SkColorGetR(pixel) > SkColorGetA(pixel) || 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColorGetG(pixel) > SkColorGetA(pixel) || 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColorGetB(pixel) > SkColorGetA(pixel)) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MakeBitmapOpaque(const SkBitmap& bitmap) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = 0; x < bitmap.width(); ++x) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < bitmap.height(); ++y) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// '0' is not a valid clip board data format. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::FormatType() : data_(0) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::FormatType(UINT native_format) : data_(native_format) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::~FormatType() { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Clipboard::FormatType::Serialize() const { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::IntToString(data_); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType Clipboard::FormatType::Deserialize( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& serialization) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int clipboard_format = -1; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt(serialization, &clipboard_format)) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FormatType(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FormatType(clipboard_format); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::Clipboard() : create_window_(false) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MessageLoop::current()->type() == MessageLoop::TYPE_UI) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a dummy HWND to be the clipboard's owner. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WNDCLASSEX window_class; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::InitializeWindowClass( 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"ClipboardOwnerWindowClass", 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &base::win::WrappedWindowProc<ClipboardOwnerWndProc>, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &window_class); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::RegisterClassEx(&window_class); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_window_ = true; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_owner_ = NULL; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::~Clipboard() { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (clipboard_owner_) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DestroyWindow(clipboard_owner_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_owner_ = NULL; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::EmptyClipboard(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ObjectMap::const_iterator iter = objects.begin(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != objects.end(); ++iter) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchObject(static_cast<ObjectType>(iter->first), iter->second); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteText(const char* text_data, size_t text_len) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF8ToUTF16(text_data, text_len, &text); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL glob = CreateGlobalData(text); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(CF_UNICODETEXT, glob); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteHTML(const char* markup_data, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t markup_len, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t url_len) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string markup(markup_data, markup_len); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_len > 0) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url.assign(url_data, url_len); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL glob = CreateGlobalData(html_fragment); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(ClipboardUtil::GetHtmlFormat()->cfFormat, glob); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteData(GetRtfFormatType(), rtf_data, data_len); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteBookmark(const char* title_data, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t title_len, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t url_len) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string bookmark(title_data, title_len); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark.append(1, L'\n'); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmark.append(url_data, url_len); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 wide_bookmark = UTF8ToWide(bookmark); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL glob = CreateGlobalData(wide_bookmark); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(ClipboardUtil::GetUrlWFormat()->cfFormat, glob); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteWebSmartPaste() { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(clipboard_owner_); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetClipboardData(ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC dc = ::GetDC(NULL); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This doesn't actually cost us a memcpy when the bitmap comes from the 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // renderer as we load it into the bitmap using setPixels which just sets a 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer. Someone has to memcpy it into GDI, it might as well be us here. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): share data in gfx/bitmap_header.cc somehow 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BITMAPINFO bm_info = {0}; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biWidth = size->width(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biHeight = -size->height(); // sets vertical orientation 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biPlanes = 1; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biBitCount = 32; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bm_info.bmiHeader.biCompression = BI_RGB; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ::CreateDIBSection allocates memory for us to copy our bitmap into. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unfortunately, we can't write the created bitmap to the clipboard, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *bits; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP source_hbitmap = 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bits && source_hbitmap) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the bitmap out of shared memory and into GDI 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(bits, pixel_data, 4 * size->width() * size->height()); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we have an HBITMAP, we can write it to the clipboard 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteBitmapFromHandle(source_hbitmap, *size); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(source_hbitmap); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ReleaseDC(NULL, dc); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We would like to just call ::SetClipboardData on the source_hbitmap, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but that bitmap might not be of a sort we can write to the clipboard. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For this reason, we create a new bitmap, copy the bits over, and then 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // write that to the clipboard. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC dc = ::GetDC(NULL); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC compatible_dc = ::CreateCompatibleDC(NULL); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC source_dc = ::CreateCompatibleDC(NULL); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the HBITMAP we will eventually write to the clipboard 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP hbitmap = ::CreateCompatibleBitmap(dc, size.width(), size.height()); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hbitmap) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Failed to create the bitmap 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(compatible_dc); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(source_dc); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ReleaseDC(NULL, dc); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP old_hbitmap = (HBITMAP)SelectObject(compatible_dc, hbitmap); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HBITMAP old_source = (HBITMAP)SelectObject(source_dc, source_hbitmap); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now we need to blend it into an HBITMAP we can place on the clipboard 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GdiAlphaBlend(compatible_dc, 0, 0, size.width(), size.height(), 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_dc, 0, 0, size.width(), size.height(), bf); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up all the handles we just opened 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SelectObject(compatible_dc, old_hbitmap); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SelectObject(source_dc, old_source); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(old_hbitmap); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(old_source); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(compatible_dc); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteDC(source_dc); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ReleaseDC(NULL, dc); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(CF_BITMAP, hbitmap); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteData(const FormatType& format, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data_data, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t data_len) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HGLOBAL hdata = ::GlobalAlloc(GMEM_MOVEABLE, data_len); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hdata) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data = static_cast<char*>(::GlobalLock(hdata)); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(data, data_data, data_len); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToClipboard(format.ToUINT(), hdata); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(clipboard_owner_); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handle && !::SetClipboardData(format, handle)) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FreeData(format, handle); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint64 Clipboard::GetSequenceNumber(Buffer buffer) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::GetClipboardSequenceNumber(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clipboard::Buffer buffer) const { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ::IsClipboardFormatAvailable(format.ToUINT()) != FALSE; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::Clear(Buffer buffer) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::EmptyClipboard(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<string16>* types, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* contains_filenames) const { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!types || !contains_filenames) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FORMATETC* text_format = ClipboardUtil::GetPlainTextFormat(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FORMATETC* html_format = ClipboardUtil::GetHtmlFormat(); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FORMATETC* rtf_format = ClipboardUtil::GetRtfFormat(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->clear(); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsClipboardFormatAvailable(text_format->cfFormat)) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeText)); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsClipboardFormatAvailable(html_format->cfFormat)) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeHTML)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsClipboardFormatAvailable(rtf_format->cfFormat)) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeRTF)); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsClipboardFormatAvailable(CF_DIB)) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypePNG)); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contains_filenames = false; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE hdata = ::GetClipboardData( 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClipboardUtil::GetWebCustomDataFormat()->cfFormat); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hdata) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadCustomDataTypes(::GlobalLock(hdata), ::GlobalSize(hdata), types); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(hdata); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->clear(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE data = ::GetClipboardData(CF_UNICODETEXT); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(static_cast<const char16*>(::GlobalLock(data))); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* result) const { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->clear(); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE data = ::GetClipboardData(CF_TEXT); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(static_cast<const char*>(::GlobalLock(data))); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* src_url, uint32* fragment_start, 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* fragment_end) const { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markup->clear(); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(dcheng): Remove these checks, I don't think they should be optional. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(src_url); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src_url) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_url->clear(); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_start = 0; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_end = 0; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE data = ::GetClipboardData(ClipboardUtil::GetHtmlFormat()->cfFormat); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cf_html(static_cast<const char*>(::GlobalLock(data))); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalUnlock(data); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t html_start = std::string::npos; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start_index = std::string::npos; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t end_index = std::string::npos; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClipboardUtil::CFHtmlExtractMetadata(cf_html, src_url, &html_start, 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &start_index, &end_index); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This might happen if the contents of the clipboard changed and CF_HTML is 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no longer available. 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_index == std::string::npos || 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_index == std::string::npos || 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) html_start == std::string::npos) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(start_index, html_start); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(end_index, html_start); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((start_index - html_start) <= kuint32max); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((end_index - html_start) <= kuint32max); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<size_t> offsets; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets.push_back(start_index - html_start); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offsets.push_back(end_index - html_start); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markup->assign(UTF8ToUTF16AndAdjustOffsets(cf_html.data() + html_start, 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &offsets)); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_start = static_cast<uint32>(offsets[0]); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_end = static_cast<uint32>(offsets[1]); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadData(GetRtfFormatType(), result); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap Clipboard::ReadImage(Buffer buffer) const { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SkBitmap(); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We use a DIB rather than a DDB here since ::GetObject() with the 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HBITMAP returned from ::GetClipboardData(CF_BITMAP) always reports a color 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // depth of 32bpp. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BITMAPINFO* bitmap = static_cast<BITMAPINFO*>(::GetClipboardData(CF_DIB)); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bitmap) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SkBitmap(); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int color_table_length = 0; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (bitmap->bmiHeader.biBitCount) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_table_length = bitmap->bmiHeader.biClrUsed 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? bitmap->bmiHeader.biClrUsed 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : 1 << bitmap->bmiHeader.biBitCount; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 16: 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 32: 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bitmap->bmiHeader.biCompression == BI_BITFIELDS) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) color_table_length = 3; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 24: 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* bitmap_bits = reinterpret_cast<const char*>(bitmap) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + bitmap->bmiHeader.biSize + color_table_length * sizeof(RGBQUAD); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Canvas canvas(gfx::Size(bitmap->bmiHeader.biWidth, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->bmiHeader.biHeight), 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::SCALE_FACTOR_100P, 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HDC dc = scoped_platform_paint.GetPlatformSurface(); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetDIBitsToDevice(dc, 0, 0, bitmap->bmiHeader.biWidth, 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->bmiHeader.biHeight, 0, 0, 0, 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->bmiHeader.biHeight, bitmap_bits, bitmap, 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DIB_RGB_COLORS); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows doesn't really handle alpha channels well in many situations. When 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the source image is < 32 bpp, we force the bitmap to be opaque. When the 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // source image is 32 bpp, the alpha channel might still contain garbage data. 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since Windows uses premultiplied alpha, we scan for instances where 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (R, G, B) > A. If there are any invalid premultiplied colors in the image, 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we assume the alpha channel contains garbage and force the bitmap to be 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opaque as well. Note that this heuristic will fail on a transparent bitmap 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // containing only black pixels... 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& device_bitmap = 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) canvas.sk_canvas()->getDevice()->accessBitmap(true); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkAutoLockPixels lock(device_bitmap); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_invalid_alpha_channel = bitmap->bmiHeader.biBitCount < 32 || 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitmapHasInvalidPremultipliedColors(device_bitmap); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_invalid_alpha_channel) { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeBitmapOpaque(device_bitmap); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas.ExtractImageRep().sk_bitmap(); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadCustomData(Buffer buffer, 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& type, 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* result) const { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(buffer, BUFFER_STANDARD); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Acquire the clipboard. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedClipboard clipboard; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard.Acquire(GetClipboardWindow())) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE hdata = ::GetClipboardData( 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClipboardUtil::GetWebCustomDataFormat()->cfFormat); 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) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE data = ::GetClipboardData(ClipboardUtil::GetUrlWFormat()->cfFormat); 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)// TODO(dcheng): Just substitue the appropriate constants here. 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetUrlFormatType() { 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetUrlFormat()->cfFormat)); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetUrlWFormatType() { 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetUrlWFormat()->cfFormat)); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetMozUrlFormatType() { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetMozUrlFormat()->cfFormat)); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetPlainTextFormat()->cfFormat)); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetPlainTextWFormat()->cfFormat)); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFilenameFormatType() { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetFilenameFormat()->cfFormat)); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetFilenameWFormat()->cfFormat)); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MS HTML Format 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetHtmlFormatType() { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetHtmlFormat()->cfFormat)); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MS RTF Format 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetRtfFormatType() { 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetRtfFormat()->cfFormat)); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetBitmapFormatType() { 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (CF_BITMAP)); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Firefox text/html 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetTextHtmlFormatType() { 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetTextHtmlFormat()->cfFormat)); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetCFHDropFormatType() { 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetCFHDropFormat()->cfFormat)); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFileDescriptorFormatType() { 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetFileDescriptorFormat()->cfFormat)); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetFileContentFormatZeroType() { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetFileContentFormatZero()->cfFormat)); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat)); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetWebCustomDataFormat()->cfFormat)); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClipboardUtil::GetPepperCustomDataFormat()->cfFormat)); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::FreeData(unsigned int format, HANDLE data) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format == CF_BITMAP) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::DeleteObject(static_cast<HBITMAP>(data)); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GlobalFree(data); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HWND Clipboard::GetClipboardWindow() const { 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard_owner_ && create_window_) { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"ClipboardOwnerWindow", 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 0, 0, 0, 0, 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND_MESSAGE, 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 0, 0); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return clipboard_owner_; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 858