// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef APP_CLIPBOARD_CLIPBOARD_H_ #define APP_CLIPBOARD_CLIPBOARD_H_ #include #include #include #include "base/process.h" #include "base/shared_memory.h" #include "base/string16.h" #include "testing/gtest/include/gtest/gtest_prod.h" namespace gfx { class Size; } class FilePath; class Clipboard { public: typedef std::string FormatType; // ObjectType designates the type of data to be stored in the clipboard. This // designation is shared across all OSes. The system-specific designation // is defined by FormatType. A single ObjectType might be represented by // several system-specific FormatTypes. For example, on Linux the CBF_TEXT // ObjectType maps to "text/plain", "STRING", and several other formats. On // windows it maps to CF_UNICODETEXT. enum ObjectType { CBF_TEXT, CBF_HTML, CBF_BOOKMARK, CBF_FILES, CBF_WEBKIT, CBF_BITMAP, CBF_SMBITMAP, // Bitmap from shared memory. CBF_DATA, // Arbitrary block of bytes. }; // ObjectMap is a map from ObjectType to associated data. // The data is organized differently for each ObjectType. The following // table summarizes what kind of data is stored for each key. // * indicates an optional argument. // // Key Arguments Type // ------------------------------------- // CBF_TEXT text char array // CBF_HTML html char array // url* char array // CBF_BOOKMARK html char array // url char array // CBF_LINK html char array // url char array // CBF_FILES files char array representing multiple files. // Filenames are separated by null characters and // the final filename is double null terminated. // The filenames are encoded in platform-specific // encoding. // CBF_WEBKIT none empty vector // CBF_BITMAP pixels byte array // size gfx::Size struct // CBF_SMBITMAP shared_mem A pointer to an unmapped base::SharedMemory // object containing the bitmap data. // size gfx::Size struct // CBF_DATA format char array // data byte array typedef std::vector ObjectMapParam; typedef std::vector ObjectMapParams; typedef std::map ObjectMap; // Buffer designates which clipboard the action should be applied to. // Only platforms that use the X Window System support the selection // buffer. Furthermore we currently only use a buffer other than the // standard buffer when reading from the clipboard so only those // functions accept a buffer parameter. enum Buffer { BUFFER_STANDARD, #if defined(USE_X11) BUFFER_SELECTION, #endif }; static bool IsValidBuffer(int32 buffer) { switch (buffer) { case BUFFER_STANDARD: return true; #if defined(USE_X11) case BUFFER_SELECTION: return true; #endif } return false; } static Buffer FromInt(int32 buffer) { return static_cast(buffer); } Clipboard(); ~Clipboard(); // Write a bunch of objects to the system clipboard. Copies are made of the // contents of |objects|. On Windows they are copied to the system clipboard. // On linux they are copied into a structure owned by the Clipboard object and // kept until the system clipboard is set again. void WriteObjects(const ObjectMap& objects); // Behaves as above. If there is some shared memory handle passed as one of // the objects, it came from the process designated by |process|. This will // assist in turning it into a shared memory region that the current process // can use. void WriteObjects(const ObjectMap& objects, base::ProcessHandle process); // On Linux/BSD, we need to know when the clipboard is set to a URL. Most // platforms don't care. #if defined(OS_WIN) || defined(OS_MACOSX) void DidWriteURL(const std::string& utf8_text) {} #else // !defined(OS_WIN) && !defined(OS_MACOSX) void DidWriteURL(const std::string& utf8_text); #endif // Tests whether the clipboard contains a certain format bool IsFormatAvailable(const FormatType& format, Buffer buffer) const; // As above, but instead of interpreting |format| by some platform-specific // definition, interpret it as a literal MIME type. bool IsFormatAvailableByString(const std::string& format, Buffer buffer) const; // Reads UNICODE text from the clipboard, if available. void ReadText(Buffer buffer, string16* result) const; // Reads ASCII text from the clipboard, if available. void ReadAsciiText(Buffer buffer, std::string* result) const; // Reads HTML from the clipboard, if available. void ReadHTML(Buffer buffer, string16* markup, std::string* src_url) const; // Reads a bookmark from the clipboard, if available. void ReadBookmark(string16* title, std::string* url) const; // Reads a file or group of files from the clipboard, if available, into the // out parameter. void ReadFile(FilePath* file) const; void ReadFiles(std::vector* files) const; // Reads raw data from the clipboard with the given format type. Stores result // as a byte vector. void ReadData(const std::string& format, std::string* result); // Get format Identifiers for various types. static FormatType GetUrlFormatType(); static FormatType GetUrlWFormatType(); static FormatType GetMozUrlFormatType(); static FormatType GetPlainTextFormatType(); static FormatType GetPlainTextWFormatType(); static FormatType GetFilenameFormatType(); static FormatType GetFilenameWFormatType(); static FormatType GetWebKitSmartPasteFormatType(); // Win: MS HTML Format, Other: Generic HTML format static FormatType GetHtmlFormatType(); static FormatType GetBitmapFormatType(); // Embeds a pointer to a SharedMemory object pointed to by |bitmap_handle| // belonging to |process| into a shared bitmap [CBF_SMBITMAP] slot in // |objects|. The pointer is deleted by DispatchObjects(). // // On non-Windows platforms, |process| is ignored. static void ReplaceSharedMemHandle(ObjectMap* objects, base::SharedMemoryHandle bitmap_handle, base::ProcessHandle process); #if defined(OS_WIN) // Firefox text/html static FormatType GetTextHtmlFormatType(); static FormatType GetCFHDropFormatType(); static FormatType GetFileDescriptorFormatType(); static FormatType GetFileContentFormatZeroType(); #endif private: FRIEND_TEST(ClipboardTest, SharedBitmapTest); void DispatchObject(ObjectType type, const ObjectMapParams& params); void WriteText(const char* text_data, size_t text_len); void WriteHTML(const char* markup_data, size_t markup_len, const char* url_data, size_t url_len); void WriteBookmark(const char* title_data, size_t title_len, const char* url_data, size_t url_len); void WriteWebSmartPaste(); void WriteBitmap(const char* pixel_data, const char* size_data); #if !defined(OS_MACOSX) // |format_name| is an ASCII string and should be NULL-terminated. // TODO(estade): port to mac. void WriteData(const char* format_name, size_t format_len, const char* data_data, size_t data_len); #endif #if defined(OS_WIN) void WriteBitmapFromHandle(HBITMAP source_hbitmap, const gfx::Size& size); // Safely write to system clipboard. Free |handle| on failure. void WriteToClipboard(unsigned int format, HANDLE handle); static void ParseBookmarkClipboardFormat(const string16& bookmark, string16* title, std::string* url); // Free a handle depending on its type (as intuited from format) static void FreeData(unsigned int format, HANDLE data); // Return the window that should be the clipboard owner, creating it // if neccessary. Marked const for lazily initialization by const methods. HWND GetClipboardWindow() const; // Mark this as mutable so const methods can still do lazy initialization. mutable HWND clipboard_owner_; // True if we can create a window. bool create_window_; #elif !defined(OS_MACOSX) // The public API is via WriteObjects() which dispatches to multiple // Write*() calls, but on GTK we must write all the clipboard types // in a single GTK call. To support this we store the current set // of data we intend to put on the clipboard on clipboard_data_ as // WriteObjects is running, and then at the end call SetGtkClipboard // which replaces whatever is on the system clipboard with the // contents of clipboard_data_. public: typedef std::map > TargetMap; private: typedef struct _GtkClipboard GtkClipboard; // Write changes to gtk clipboard. void SetGtkClipboard(); // Insert a mapping into clipboard_data_. void InsertMapping(const char* key, char* data, size_t data_len); // Find the gtk clipboard for the passed buffer enum. GtkClipboard* LookupBackingClipboard(Buffer clipboard) const; TargetMap* clipboard_data_; GtkClipboard* clipboard_; GtkClipboard* primary_selection_; #endif DISALLOW_COPY_AND_ASSIGN(Clipboard); }; #endif // APP_CLIPBOARD_CLIPBOARD_H_