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)#ifndef UI_BASE_CLIPBOARD_CLIPBOARD_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_BASE_CLIPBOARD_CLIPBOARD_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/scoped_ptr.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/shared_memory.h" 16a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h" 175e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/thread_checker.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_export.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdk.h> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN) 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <objidl.h> 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#elif defined(OS_ANDROID) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <jni.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/scoped_java_ref.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA) && defined(USE_X11) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FilePath; 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace win { 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass MessageWindow; 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace win 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace base 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Size; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SkBitmap; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _GtkClipboard GtkClipboard; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __OBJC__ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@class NSString; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NSString; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClipboardTest; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UI_EXPORT Clipboard : NON_EXPORTED_BASE(public base::ThreadChecker) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MIME type constants. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kMimeTypeText[]; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kMimeTypeURIList[]; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kMimeTypeDownloadURL[]; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kMimeTypeHTML[]; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kMimeTypeRTF[]; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kMimeTypePNG[]; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Platform neutral holder for native data representation of a clipboard type. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct UI_EXPORT FormatType { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~FormatType(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Serializes and deserializes a FormatType for use in IPC messages. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string Serialize() const; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static FormatType Deserialize(const std::string& serialization); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(USE_AURA) 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // FormatType can be used in a set on some platforms. 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool operator<(const FormatType& other) const; 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const FORMATETC& ToFormatEtc() const { return data_; } 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#elif defined(OS_MACOSX) 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Custom copy and assignment constructor to handle NSString. 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType(const FormatType& other); 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType& operator=(const FormatType& other); 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#elif defined(USE_AURA) 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& ToString() const { return data_; } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class Clipboard; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Equals(const FormatType& other) const; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Platform-specific glue used internally by the Clipboard class. Each 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // plaform should define,at least one of each of the following: 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 1. A constructor that wraps that native clipboard format descriptor. 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 2. An accessor to retrieve the wrapped descriptor. 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 3. A data member to hold the wrapped descriptor. 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Note that in some cases, the accessor for the wrapped descriptor may be 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // public, as these format types can be used by drag and drop code as well. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FormatType(UINT native_format); 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FormatType(UINT native_format, LONG index); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UINT ToUINT() const { return data_.cfFormat; } 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FORMATETC data_; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FormatType(NSString* native_format); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* ToNSString() const { return data_; } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* data_; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(USE_AURA) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FormatType(const std::string& native_format); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string data_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(TOOLKIT_GTK) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FormatType(const std::string& native_format); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FormatType(const GdkAtom& native_format); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GdkAtom& ToGdkAtom() const { return data_; } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkAtom data_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_ANDROID) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit FormatType(const std::string& native_format); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& data() const { return data_; } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string data_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error No FormatType definition. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Copyable and assignable, since this is essentially an opaque value type. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ObjectType designates the type of data to be stored in the clipboard. This 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // designation is shared across all OSes. The system-specific designation 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is defined by FormatType. A single ObjectType might be represented by 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // several system-specific FormatTypes. For example, on Linux the CBF_TEXT 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ObjectType maps to "text/plain", "STRING", and several other formats. On 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // windows it maps to CF_UNICODETEXT. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ObjectType { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_TEXT, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_HTML, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_RTF, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_BOOKMARK, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_FILES, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_WEBKIT, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_BITMAP, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_SMBITMAP, // Bitmap from shared memory. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBF_DATA, // Arbitrary block of bytes. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ObjectMap is a map from ObjectType to associated data. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The data is organized differently for each ObjectType. The following 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // table summarizes what kind of data is stored for each key. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // * indicates an optional argument. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Key Arguments Type 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ------------------------------------- 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_TEXT text char array 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_HTML html char array 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // url* char array 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_RTF data byte array 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_BOOKMARK html char array 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // url char array 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_LINK html char array 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // url char array 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_FILES files char array representing multiple files. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filenames are separated by null characters and 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the final filename is double null terminated. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The filenames are encoded in platform-specific 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // encoding. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_WEBKIT none empty vector 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_BITMAP pixels byte array 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size gfx::Size struct 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_SMBITMAP shared_mem A pointer to an unmapped base::SharedMemory 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object containing the bitmap data. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size gfx::Size struct 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CBF_DATA format char array 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data byte array 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<char> ObjectMapParam; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<ObjectMapParam> ObjectMapParams; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int /* ObjectType */, ObjectMapParams> ObjectMap; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffer designates which clipboard the action should be applied to. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only platforms that use the X Window System support the selection 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffer. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Buffer { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUFFER_STANDARD, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUFFER_SELECTION, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsValidBuffer(int32 buffer) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (buffer) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BUFFER_STANDARD: 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_X11) && !defined(OS_CHROMEOS) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BUFFER_SELECTION: 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static Buffer FromInt(int32 buffer) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<Buffer>(buffer); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the list of threads that are allowed to access the clipboard. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SetAllowedThreads( 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<base::PlatformThreadId>& allowed_threads); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the clipboard object for the current thread. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Most implementations will have at most one clipboard which will live on 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the main UI thread, but Windows has tricky semantics where there have to 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be two clipboards: one that lives on the UI thread and one that lives on 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the IO thread. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static Clipboard* GetForCurrentThread(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroys the clipboard for the current thread. Usually, this will clean up 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // all clipboards, except on Windows. (Previous code leaks the IO thread 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clipboard, so it shouldn't be a problem.) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DestroyClipboardForCurrentThread(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write a bunch of objects to the system clipboard. Copies are made of the 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contents of |objects|. On Windows they are copied to the system clipboard. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On linux they are copied into a structure owned by the Clipboard object and 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // kept until the system clipboard is set again. 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void WriteObjects(Buffer buffer, const ObjectMap& objects); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a sequence number which uniquely identifies clipboard state. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can be used to version the data on the clipboard and determine 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // whether it has changed. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 GetSequenceNumber(Buffer buffer); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tests whether the clipboard contains a certain format 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsFormatAvailable(const FormatType& format, Buffer buffer) const; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the clipboard data. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Clear(Buffer buffer); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadAvailableTypes(Buffer buffer, std::vector<string16>* types, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* contains_filenames) const; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads UNICODE text from the clipboard, if available. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadText(Buffer buffer, string16* result) const; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads ASCII text from the clipboard, if available. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadAsciiText(Buffer buffer, std::string* result) const; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads HTML from the clipboard, if available. If the HTML fragment requires 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // context to parse, |fragment_start| and |fragment_end| are indexes into 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // markup indicating the beginning and end of the actual fragment. Otherwise, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they will contain 0 and markup->size(). 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadHTML(Buffer buffer, string16* markup, std::string* src_url, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* fragment_start, uint32* fragment_end) const; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads RTF from the clipboard, if available. Stores the result as a byte 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // vector. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadRTF(Buffer buffer, std::string* result) const; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads an image from the clipboard, if available. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap ReadImage(Buffer buffer) const; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadCustomData(Buffer buffer, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& type, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* result) const; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads a bookmark from the clipboard, if available. 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadBookmark(string16* title, std::string* url) const; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads raw data from the clipboard with the given format type. Stores result 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as a byte vector. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadData(const FormatType& format, std::string* result) const; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the FormatType corresponding to an arbitrary format string, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // registering it with the system if needed. Due to Windows/Linux 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // limitiations, |format_string| must never be controlled by the user. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static FormatType GetFormatType(const std::string& format_string); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get format identifiers for various types. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetUrlFormatType(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetUrlWFormatType(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetMozUrlFormatType(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetPlainTextFormatType(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetPlainTextWFormatType(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetFilenameFormatType(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetFilenameWFormatType(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetWebKitSmartPasteFormatType(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Win: MS HTML Format, Other: Generic HTML format 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetHtmlFormatType(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetRtfFormatType(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetBitmapFormatType(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(raymes): Unify web custom data and pepper custom data: 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // crbug.com/158399. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetWebCustomDataFormatType(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetPepperCustomDataFormatType(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Embeds a pointer to a SharedMemory object pointed to by |bitmap_handle| 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // belonging to |process| into a shared bitmap [CBF_SMBITMAP] slot in 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |objects|. The pointer is deleted by DispatchObjects(). 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On non-Windows platforms, |process| is ignored. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void ReplaceSharedMemHandle(ObjectMap* objects, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle bitmap_handle, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle process); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Firefox text/html 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetTextHtmlFormatType(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetCFHDropFormatType(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FormatType& GetFileDescriptorFormatType(); 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static const FormatType& GetFileContentZeroFormatType(); 3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) static const FormatType& GetIDListFormatType(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClipboardTest, SharedBitmapTest); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ClipboardTest, EmptyHTMLTest); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ClipboardTest; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clipboard(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Clipboard(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DispatchObject(ObjectType type, const ObjectMapParams& params); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteText(const char* text_data, size_t text_len); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteHTML(const char* markup_data, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t markup_len, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t url_len); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteRTF(const char* rtf_data, size_t data_len); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteBookmark(const char* title_data, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t title_len, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t url_len); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteWebSmartPaste(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteBitmap(const char* pixel_data, const char* size_data); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteData(const FormatType& format, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data_data, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t data_len); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteBitmapFromHandle(HBITMAP source_hbitmap, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Safely write to system clipboard. Free |handle| on failure. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteToClipboard(unsigned int format, HANDLE handle); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void ParseBookmarkClipboardFormat(const string16& bookmark, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* title, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* url); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Free a handle depending on its type (as intuited from format) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void FreeData(unsigned int format, HANDLE data); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return the window that should be the clipboard owner, creating it 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if neccessary. Marked const for lazily initialization by const methods. 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND GetClipboardWindow() const; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark this as mutable so const methods can still do lazy initialization. 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mutable scoped_ptr<base::win::MessageWindow> clipboard_owner_; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(TOOLKIT_GTK) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The public API is via WriteObjects() which dispatches to multiple 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write*() calls, but on GTK we must write all the clipboard types 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in a single GTK call. To support this we store the current set 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of data we intend to put on the clipboard on clipboard_data_ as 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WriteObjects is running, and then at the end call SetGtkClipboard 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which replaces whatever is on the system clipboard with the 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contents of clipboard_data_. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string, std::pair<char*, size_t> > TargetMap; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write changes to gtk clipboard. 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetGtkClipboard(Buffer buffer); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert a mapping into clipboard_data_. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InsertMapping(const char* key, char* data, size_t data_len); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the gtk clipboard for the passed buffer enum. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkClipboard* LookupBackingClipboard(Buffer clipboard) const; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TargetMap* clipboard_data_; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkClipboard* clipboard_; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkClipboard* primary_selection_; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(USE_AURA) && defined(USE_X11) && !defined(OS_CHROMEOS) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We keep our implementation details private because otherwise we bring in 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the X11 headers and break chrome compile. 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class AuraX11Details; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AuraX11Details> aurax11_details_; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Clipboard); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // UI_BASE_CLIPBOARD_CLIPBOARD_H_ 413