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