diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-10 21:08:21 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-10 21:08:21 +0000 |
commit | 2dfeaf9c751b9ff269ca8bcd8f9e4902a0c9012c (patch) | |
tree | 86e7ab4c054af5723245dc0bdead5c08a308a466 /app | |
parent | 6f1d18ebd4dd4315b02197c4593ad905a9049f8b (diff) | |
download | chromium_src-2dfeaf9c751b9ff269ca8bcd8f9e4902a0c9012c.zip chromium_src-2dfeaf9c751b9ff269ca8bcd8f9e4902a0c9012c.tar.gz chromium_src-2dfeaf9c751b9ff269ca8bcd8f9e4902a0c9012c.tar.bz2 |
Move clipboard from app/ to ui/base
BUG=none
TEST=none
TBR=brettw
Review URL: http://codereview.chromium.org/6135006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70938 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r-- | app/DEPS | 1 | ||||
-rw-r--r-- | app/app.gyp | 2 | ||||
-rw-r--r-- | app/app_base.gypi | 9 | ||||
-rw-r--r-- | app/clipboard/clipboard.cc | 180 | ||||
-rw-r--r-- | app/clipboard/clipboard.h | 270 | ||||
-rw-r--r-- | app/clipboard/clipboard_linux.cc | 417 | ||||
-rw-r--r-- | app/clipboard/clipboard_mac.mm | 329 | ||||
-rw-r--r-- | app/clipboard/clipboard_unittest.cc | 428 | ||||
-rw-r--r-- | app/clipboard/clipboard_util_win.cc | 540 | ||||
-rw-r--r-- | app/clipboard/clipboard_util_win.h | 66 | ||||
-rw-r--r-- | app/clipboard/clipboard_win.cc | 602 | ||||
-rw-r--r-- | app/clipboard/scoped_clipboard_writer.cc | 136 | ||||
-rw-r--r-- | app/clipboard/scoped_clipboard_writer.h | 80 | ||||
-rw-r--r-- | app/os_exchange_data_provider_win.cc | 4 | ||||
-rw-r--r-- | app/os_exchange_data_win_unittest.cc | 4 |
15 files changed, 7 insertions, 3061 deletions
@@ -5,6 +5,7 @@ include_rules = [ "+net", "+skia", "+third_party/mozilla", + "+ui", "-chrome", "-third_party/WebKit", diff --git a/app/app.gyp b/app/app.gyp index f15b44d..a0435f8 100644 --- a/app/app.gyp +++ b/app/app.gyp @@ -36,10 +36,10 @@ '../third_party/icu/icu.gyp:icuuc', '../third_party/libpng/libpng.gyp:libpng', '../third_party/zlib/zlib.gyp:zlib', + '../ui/ui.gyp:ui_base', '<(libjpeg_gyp_path):libjpeg', ], 'sources': [ - 'clipboard/clipboard_unittest.cc', 'data_pack_unittest.cc', 'l10n_util_mac_unittest.mm', 'l10n_util_unittest.cc', diff --git a/app/app_base.gypi b/app/app_base.gypi index 3f27573..1431ce1 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -92,15 +92,6 @@ 'active_window_watcher_x.cc', 'active_window_watcher_x.h', 'bidi_line_iterator.cc', - 'clipboard/clipboard.cc', - 'clipboard/clipboard.h', - 'clipboard/clipboard_linux.cc', - 'clipboard/clipboard_mac.mm', - 'clipboard/clipboard_util_win.cc', - 'clipboard/clipboard_util_win.h', - 'clipboard/clipboard_win.cc', - 'clipboard/scoped_clipboard_writer.cc', - 'clipboard/scoped_clipboard_writer.h', 'combobox_model.h', 'data_pack.cc', 'data_pack.h', diff --git a/app/clipboard/clipboard.cc b/app/clipboard/clipboard.cc deleted file mode 100644 index fa4f5a5..0000000 --- a/app/clipboard/clipboard.cc +++ /dev/null @@ -1,180 +0,0 @@ -// 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. - -#include "app/clipboard/clipboard.h" - -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "gfx/size.h" - -namespace { - -// A compromised renderer could send us bad data, so validate it. -// This function only checks that the size parameter makes sense, the caller -// is responsible for further validating the bitmap buffer against -// |bitmap_bytes|. -// -// |params| - Clipboard bitmap contents to validate. -// |bitmap_bytes| - On return contains the number of bytes needed to store -// the bitmap data or -1 if the data is invalid. -// returns: true if the bitmap size is valid, false otherwise. -bool IsBitmapSafe(const Clipboard::ObjectMapParams& params, - uint32* bitmap_bytes) { - *bitmap_bytes = -1; - if (params[1].size() != sizeof(gfx::Size)) - return false; - const gfx::Size* size = - reinterpret_cast<const gfx::Size*>(&(params[1].front())); - uint32 total_size = size->width(); - // Using INT_MAX not SIZE_T_MAX to put a reasonable bound on things. - if (INT_MAX / size->width() <= size->height()) - return false; - total_size *= size->height(); - if (INT_MAX / total_size <= 4) - return false; - total_size *= 4; - *bitmap_bytes = total_size; - return true; -} - -// Validates a plain bitmap on the clipboard. -// Returns true if the clipboard data makes sense and it's safe to access the -// bitmap. -bool ValidatePlainBitmap(const Clipboard::ObjectMapParams& params) { - uint32 bitmap_bytes = -1; - if (!IsBitmapSafe(params, &bitmap_bytes)) - return false; - if (bitmap_bytes != params[0].size()) - return false; - return true; -} - -// Valides a shared bitmap on the clipboard. -// Returns true if the clipboard data makes sense and it's safe to access the -// bitmap. -bool ValidateAndMapSharedBitmap(const Clipboard::ObjectMapParams& params, - base::SharedMemory* bitmap_data) { - using base::SharedMemory; - uint32 bitmap_bytes = -1; - if (!IsBitmapSafe(params, &bitmap_bytes)) - return false; - - if (!bitmap_data || !SharedMemory::IsHandleValid(bitmap_data->handle())) - return false; - - if (!bitmap_data->Map(bitmap_bytes)) { - PLOG(ERROR) << "Failed to map bitmap memory"; - return false; - } - return true; -} - -} // namespace - -void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) { - // All types apart from CBF_WEBKIT need at least 1 non-empty param. - if (type != CBF_WEBKIT && (params.empty() || params[0].empty())) - return; - // Some other types need a non-empty 2nd param. - if ((type == CBF_BOOKMARK || type == CBF_BITMAP || - type == CBF_SMBITMAP || type == CBF_DATA) && - (params.size() != 2 || params[1].empty())) - return; - switch (type) { - case CBF_TEXT: - WriteText(&(params[0].front()), params[0].size()); - break; - - case CBF_HTML: - if (params.size() == 2) { - if (params[1].empty()) - return; - WriteHTML(&(params[0].front()), params[0].size(), - &(params[1].front()), params[1].size()); - } else if (params.size() == 1) { - WriteHTML(&(params[0].front()), params[0].size(), NULL, 0); - } - break; - - case CBF_BOOKMARK: - WriteBookmark(&(params[0].front()), params[0].size(), - &(params[1].front()), params[1].size()); - break; - - case CBF_WEBKIT: - WriteWebSmartPaste(); - break; - - case CBF_BITMAP: - if (!ValidatePlainBitmap(params)) - return; - - WriteBitmap(&(params[0].front()), &(params[1].front())); - break; - - case CBF_SMBITMAP: { - using base::SharedMemory; - using base::SharedMemoryHandle; - - if (params[0].size() != sizeof(SharedMemory*)) - return; - - // It's OK to cast away constness here since we map the handle as - // read-only. - const char* raw_bitmap_data_const = - reinterpret_cast<const char*>(&(params[0].front())); - char* raw_bitmap_data = const_cast<char*>(raw_bitmap_data_const); - scoped_ptr<SharedMemory> bitmap_data( - *reinterpret_cast<SharedMemory**>(raw_bitmap_data)); - - if (!ValidateAndMapSharedBitmap(params, bitmap_data.get())) - return; - WriteBitmap(static_cast<const char*>(bitmap_data->memory()), - &(params[1].front())); - break; - } - -#if !defined(OS_MACOSX) - case CBF_DATA: - WriteData(&(params[0].front()), params[0].size(), - &(params[1].front()), params[1].size()); - break; -#endif // !defined(OS_MACOSX) - - default: - NOTREACHED(); - } -} - -// static -void Clipboard::ReplaceSharedMemHandle(ObjectMap* objects, - base::SharedMemoryHandle bitmap_handle, - base::ProcessHandle process) { - using base::SharedMemory; - bool has_shared_bitmap = false; - - for (ObjectMap::iterator iter = objects->begin(); iter != objects->end(); - ++iter) { - if (iter->first == CBF_SMBITMAP) { - // The code currently only accepts sending a single bitmap over this way. - // Fail hard if we ever encounter more than one shared bitmap structure to - // fill. - CHECK(!has_shared_bitmap); - -#if defined(OS_WIN) - SharedMemory* bitmap = new SharedMemory(bitmap_handle, true, process); -#else - SharedMemory* bitmap = new SharedMemory(bitmap_handle, true); -#endif - - // We store the shared memory object pointer so it can be retrieved by the - // UI thread (see DispatchObject()). - iter->second[0].clear(); - for (size_t i = 0; i < sizeof(SharedMemory*); ++i) - iter->second[0].push_back(reinterpret_cast<char*>(&bitmap)[i]); - has_shared_bitmap = true; - } - } -} - diff --git a/app/clipboard/clipboard.h b/app/clipboard/clipboard.h deleted file mode 100644 index 47a68f2..0000000 --- a/app/clipboard/clipboard.h +++ /dev/null @@ -1,270 +0,0 @@ -// 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_ -#pragma once - -#include <map> -#include <string> -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/process.h" -#include "base/shared_memory.h" -#include "base/string16.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<char> ObjectMapParam; - typedef std::vector<ObjectMapParam> ObjectMapParams; - typedef std::map<int /* ObjectType */, ObjectMapParams> 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, - BUFFER_SELECTION, - BUFFER_DRAG, - }; - - static bool IsValidBuffer(int32 buffer) { - switch (buffer) { - case BUFFER_STANDARD: - return true; -#if defined(USE_X11) - case BUFFER_SELECTION: - return true; -#endif - case BUFFER_DRAG: - return true; - } - return false; - } - - static Buffer FromInt(int32 buffer) { - return static_cast<Buffer>(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<FilePath>* files) const; - - // Reads raw data from the clipboard with the given format type. Stores result - // as a byte vector. - // TODO(dcheng): Due to platform limitations on Windows, we should make sure - // format is never controlled by the user. - 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_ALL_PREFIXES(ClipboardTest, SharedBitmapTest); - FRIEND_TEST_ALL_PREFIXES(ClipboardTest, EmptyHTMLTest); - - 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<FormatType, std::pair<char*, size_t> > 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_ diff --git a/app/clipboard/clipboard_linux.cc b/app/clipboard/clipboard_linux.cc deleted file mode 100644 index 8408614e..0000000 --- a/app/clipboard/clipboard_linux.cc +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (c) 2010 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. - -#include "app/clipboard/clipboard.h" - -#include <gtk/gtk.h> -#include <map> -#include <set> -#include <string> -#include <utility> - -#include "base/file_path.h" -#include "base/logging.h" -#include "base/scoped_ptr.h" -#include "base/utf_string_conversions.h" -#include "gfx/gtk_util.h" -#include "gfx/size.h" - -namespace { - -const char kMimeBmp[] = "image/bmp"; -const char kMimeHtml[] = "text/html"; -const char kMimeText[] = "text/plain"; -const char kMimeMozillaUrl[] = "text/x-moz-url"; -const char kMimeWebkitSmartPaste[] = "chromium/x-webkit-paste"; - -std::string GdkAtomToString(const GdkAtom& atom) { - gchar* name = gdk_atom_name(atom); - std::string rv(name); - g_free(name); - return rv; -} - -GdkAtom StringToGdkAtom(const std::string& str) { - return gdk_atom_intern(str.c_str(), FALSE); -} - -// GtkClipboardGetFunc callback. -// GTK will call this when an application wants data we copied to the clipboard. -void GetData(GtkClipboard* clipboard, - GtkSelectionData* selection_data, - guint info, - gpointer user_data) { - Clipboard::TargetMap* data_map = - reinterpret_cast<Clipboard::TargetMap*>(user_data); - - std::string target_string = GdkAtomToString(selection_data->target); - Clipboard::TargetMap::iterator iter = data_map->find(target_string); - - if (iter == data_map->end()) - return; - - if (target_string == kMimeBmp) { - gtk_selection_data_set_pixbuf(selection_data, - reinterpret_cast<GdkPixbuf*>(iter->second.first)); - } else { - gtk_selection_data_set(selection_data, selection_data->target, 8, - reinterpret_cast<guchar*>(iter->second.first), - iter->second.second); - } -} - -// GtkClipboardClearFunc callback. -// We are guaranteed this will be called exactly once for each call to -// gtk_clipboard_set_with_data. -void ClearData(GtkClipboard* clipboard, - gpointer user_data) { - Clipboard::TargetMap* map = - reinterpret_cast<Clipboard::TargetMap*>(user_data); - // The same data may be inserted under multiple keys, so use a set to - // uniq them. - std::set<char*> ptrs; - - for (Clipboard::TargetMap::iterator iter = map->begin(); - iter != map->end(); ++iter) { - if (iter->first == kMimeBmp) - g_object_unref(reinterpret_cast<GdkPixbuf*>(iter->second.first)); - else - ptrs.insert(iter->second.first); - } - - for (std::set<char*>::iterator iter = ptrs.begin(); - iter != ptrs.end(); ++iter) { - delete[] *iter; - } - - delete map; -} - -// Called on GdkPixbuf destruction; see WriteBitmap(). -void GdkPixbufFree(guchar* pixels, gpointer data) { - free(pixels); -} - -} // namespace - -Clipboard::Clipboard() : clipboard_data_(NULL) { - clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); - primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); -} - -Clipboard::~Clipboard() { - gtk_clipboard_store(clipboard_); -} - -void Clipboard::WriteObjects(const ObjectMap& objects) { - clipboard_data_ = new TargetMap(); - - for (ObjectMap::const_iterator iter = objects.begin(); - iter != objects.end(); ++iter) { - DispatchObject(static_cast<ObjectType>(iter->first), iter->second); - } - - SetGtkClipboard(); -} - -// When a URL is copied from a render view context menu (via "copy link -// location", for example), we additionally stick it in the X clipboard. This -// matches other linux browsers. -void Clipboard::DidWriteURL(const std::string& utf8_text) { - gtk_clipboard_set_text(primary_selection_, utf8_text.c_str(), - utf8_text.length()); -} - -// Take ownership of the GTK clipboard and inform it of the targets we support. -void Clipboard::SetGtkClipboard() { - scoped_array<GtkTargetEntry> targets( - new GtkTargetEntry[clipboard_data_->size()]); - - int i = 0; - for (Clipboard::TargetMap::iterator iter = clipboard_data_->begin(); - iter != clipboard_data_->end(); ++iter, ++i) { - targets[i].target = const_cast<char*>(iter->first.c_str()); - targets[i].flags = 0; - targets[i].info = 0; - } - - if (gtk_clipboard_set_with_data(clipboard_, targets.get(), - clipboard_data_->size(), - GetData, ClearData, - clipboard_data_)) { - gtk_clipboard_set_can_store(clipboard_, - targets.get(), - clipboard_data_->size()); - } - - // clipboard_data_ now owned by the GtkClipboard. - clipboard_data_ = NULL; -} - -void Clipboard::WriteText(const char* text_data, size_t text_len) { - char* data = new char[text_len]; - memcpy(data, text_data, text_len); - - InsertMapping(kMimeText, data, text_len); - InsertMapping("TEXT", data, text_len); - InsertMapping("STRING", data, text_len); - InsertMapping("UTF8_STRING", data, text_len); - InsertMapping("COMPOUND_TEXT", data, text_len); -} - -void Clipboard::WriteHTML(const char* markup_data, - size_t markup_len, - const char* url_data, - size_t url_len) { - // TODO(estade): We need to expand relative links with |url_data|. - static const char* html_prefix = "<meta http-equiv=\"content-type\" " - "content=\"text/html; charset=utf-8\">"; - size_t html_prefix_len = strlen(html_prefix); - size_t total_len = html_prefix_len + markup_len + 1; - - char* data = new char[total_len]; - snprintf(data, total_len, "%s", html_prefix); - memcpy(data + html_prefix_len, markup_data, markup_len); - // Some programs expect NULL-terminated data. See http://crbug.com/42624 - data[total_len - 1] = '\0'; - - InsertMapping(kMimeHtml, data, total_len); -} - -// Write an extra flavor that signifies WebKit was the last to modify the -// pasteboard. This flavor has no data. -void Clipboard::WriteWebSmartPaste() { - InsertMapping(kMimeWebkitSmartPaste, NULL, 0); -} - -void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { - const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); - - guchar* data = - gfx::BGRAToRGBA(reinterpret_cast<const uint8_t*>(pixel_data), - size->width(), size->height(), 0); - - GdkPixbuf* pixbuf = - gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, - 8, size->width(), size->height(), - size->width() * 4, GdkPixbufFree, NULL); - // We store the GdkPixbuf*, and the size_t half of the pair is meaningless. - // Note that this contrasts with the vast majority of entries in our target - // map, which directly store the data and its length. - InsertMapping(kMimeBmp, reinterpret_cast<char*>(pixbuf), 0); -} - -void Clipboard::WriteBookmark(const char* title_data, size_t title_len, - const char* url_data, size_t url_len) { - // Write as a mozilla url (UTF16: URL, newline, title). - string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); - string16 title = UTF8ToUTF16(std::string(title_data, title_len)); - int data_len = 2 * (title.length() + url.length()); - - char* data = new char[data_len]; - memcpy(data, url.data(), 2 * url.length()); - memcpy(data + 2 * url.length(), title.data(), 2 * title.length()); - InsertMapping(kMimeMozillaUrl, data, data_len); -} - -void Clipboard::WriteData(const char* format_name, size_t format_len, - const char* data_data, size_t data_len) { - std::string format(format_name, format_len); - // We assume that certain mapping types are only written by trusted code. - // Therefore we must upkeep their integrity. - if (format == kMimeBmp) - return; - char* data = new char[data_len]; - memcpy(data, data_data, data_len); - InsertMapping(format.c_str(), data, data_len); -} - -// We do not use gtk_clipboard_wait_is_target_available because of -// a bug with the gtk clipboard. It caches the available targets -// and does not always refresh the cache when it is appropriate. -bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, - Clipboard::Buffer buffer) const { - GtkClipboard* clipboard = LookupBackingClipboard(buffer); - if (clipboard == NULL) - return false; - - bool format_is_plain_text = GetPlainTextFormatType() == format; - if (format_is_plain_text) { - // This tries a number of common text targets. - if (gtk_clipboard_wait_is_text_available(clipboard)) - return true; - } - - bool retval = false; - GdkAtom* targets = NULL; - GtkSelectionData* data = - gtk_clipboard_wait_for_contents(clipboard, - gdk_atom_intern("TARGETS", false)); - - if (!data) - return false; - - int num = 0; - gtk_selection_data_get_targets(data, &targets, &num); - - // Some programs post data to the clipboard without any targets. If this is - // the case we attempt to make sense of the contents as text. This is pretty - // unfortunate since it means we have to actually copy the data to see if it - // is available, but at least this path shouldn't be hit for conforming - // programs. - if (num <= 0) { - if (format_is_plain_text) { - gchar* text = gtk_clipboard_wait_for_text(clipboard); - if (text) { - g_free(text); - retval = true; - } - } - } - - GdkAtom format_atom = StringToGdkAtom(format); - - for (int i = 0; i < num; i++) { - if (targets[i] == format_atom) { - retval = true; - break; - } - } - - g_free(targets); - gtk_selection_data_free(data); - - return retval; -} - -bool Clipboard::IsFormatAvailableByString(const std::string& format, - Clipboard::Buffer buffer) const { - return IsFormatAvailable(format, buffer); -} - -void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { - GtkClipboard* clipboard = LookupBackingClipboard(buffer); - if (clipboard == NULL) - return; - - result->clear(); - gchar* text = gtk_clipboard_wait_for_text(clipboard); - - if (text == NULL) - return; - - // TODO(estade): do we want to handle the possible error here? - UTF8ToUTF16(text, strlen(text), result); - g_free(text); -} - -void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, - std::string* result) const { - GtkClipboard* clipboard = LookupBackingClipboard(buffer); - if (clipboard == NULL) - return; - - result->clear(); - gchar* text = gtk_clipboard_wait_for_text(clipboard); - - if (text == NULL) - return; - - result->assign(text); - g_free(text); -} - -void Clipboard::ReadFile(FilePath* file) const { - *file = FilePath(); -} - -// TODO(estade): handle different charsets. -// TODO(port): set *src_url. -void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, - std::string* src_url) const { - GtkClipboard* clipboard = LookupBackingClipboard(buffer); - if (clipboard == NULL) - return; - markup->clear(); - - GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, - StringToGdkAtom(GetHtmlFormatType())); - - if (!data) - return; - - // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is - // UTF-16, otherwise assume UTF-8. - if (data->length >= 2 && - reinterpret_cast<uint16_t*>(data->data)[0] == 0xFEFF) { - markup->assign(reinterpret_cast<uint16_t*>(data->data) + 1, - (data->length / 2) - 1); - } else { - UTF8ToUTF16(reinterpret_cast<char*>(data->data), data->length, markup); - } - - // If there is a terminating NULL, drop it. - if (!markup->empty() && markup->at(markup->length() - 1) == '\0') - markup->resize(markup->length() - 1); - - gtk_selection_data_free(data); -} - -void Clipboard::ReadBookmark(string16* title, std::string* url) const { - // TODO(estade): implement this. - NOTIMPLEMENTED(); -} - -void Clipboard::ReadData(const std::string& format, std::string* result) { - GtkSelectionData* data = - gtk_clipboard_wait_for_contents(clipboard_, StringToGdkAtom(format)); - if (!data) - return; - result->assign(reinterpret_cast<char*>(data->data), data->length); - gtk_selection_data_free(data); -} - -// static -Clipboard::FormatType Clipboard::GetPlainTextFormatType() { - return GdkAtomToString(GDK_TARGET_STRING); -} - -// static -Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { - return GetPlainTextFormatType(); -} - -// static -Clipboard::FormatType Clipboard::GetHtmlFormatType() { - return std::string(kMimeHtml); -} - -// static -Clipboard::FormatType Clipboard::GetBitmapFormatType() { - return std::string(kMimeBmp); -} - -// static -Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { - return std::string(kMimeWebkitSmartPaste); -} - -void Clipboard::InsertMapping(const char* key, - char* data, - size_t data_len) { - DCHECK(clipboard_data_->find(key) == clipboard_data_->end()); - (*clipboard_data_)[key] = std::make_pair(data, data_len); -} - -GtkClipboard* Clipboard::LookupBackingClipboard(Buffer clipboard) const { - switch (clipboard) { - case BUFFER_STANDARD: - return clipboard_; - case BUFFER_SELECTION: - return primary_selection_; - default: - NOTREACHED(); - return NULL; - } -} diff --git a/app/clipboard/clipboard_mac.mm b/app/clipboard/clipboard_mac.mm deleted file mode 100644 index d789c58..0000000 --- a/app/clipboard/clipboard_mac.mm +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) 2010 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. - -#include "app/clipboard/clipboard.h" - -#import <Cocoa/Cocoa.h> - -#include "base/file_path.h" -#include "base/logging.h" -#include "base/mac/mac_util.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/scoped_nsobject.h" -#include "base/sys_string_conversions.h" -#include "base/utf_string_conversions.h" -#include "gfx/size.h" -#import "third_party/mozilla/NSPasteboard+Utils.h" - -namespace { - -// Would be nice if this were in UTCoreTypes.h, but it isn't -NSString* const kUTTypeURLName = @"public.url-name"; - -// Tells us if WebKit was the last to write to the pasteboard. There's no -// actual data associated with this type. -NSString* const kWebSmartPastePboardType = @"NeXT smart paste pasteboard type"; - -NSPasteboard* GetPasteboard() { - // The pasteboard should not be nil in a UI session, but this handy DCHECK - // can help track down problems if someone tries using clipboard code outside - // of a UI session. - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - DCHECK(pasteboard); - return pasteboard; -} - -} // namespace - -Clipboard::Clipboard() { -} - -Clipboard::~Clipboard() { -} - -void Clipboard::WriteObjects(const ObjectMap& objects) { - NSPasteboard* pb = GetPasteboard(); - [pb declareTypes:[NSArray array] owner:nil]; - - for (ObjectMap::const_iterator iter = objects.begin(); - iter != objects.end(); ++iter) { - DispatchObject(static_cast<ObjectType>(iter->first), iter->second); - } - -} - -void Clipboard::WriteText(const char* text_data, size_t text_len) { - std::string text_str(text_data, text_len); - NSString *text = base::SysUTF8ToNSString(text_str); - NSPasteboard* pb = GetPasteboard(); - [pb addTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; - [pb setString:text forType:NSStringPboardType]; -} - -void Clipboard::WriteHTML(const char* markup_data, - size_t markup_len, - const char* url_data, - size_t url_len) { - // We need to mark it as utf-8. (see crbug.com/11957) - std::string html_fragment_str("<meta charset='utf-8'>"); - html_fragment_str.append(markup_data, markup_len); - NSString *html_fragment = base::SysUTF8ToNSString(html_fragment_str); - - // TODO(avi): url_data? - NSPasteboard* pb = GetPasteboard(); - [pb addTypes:[NSArray arrayWithObject:NSHTMLPboardType] owner:nil]; - [pb setString:html_fragment forType:NSHTMLPboardType]; -} - -void Clipboard::WriteBookmark(const char* title_data, - size_t title_len, - const char* url_data, - size_t url_len) { - std::string title_str(title_data, title_len); - NSString *title = base::SysUTF8ToNSString(title_str); - std::string url_str(url_data, url_len); - NSString *url = base::SysUTF8ToNSString(url_str); - - // TODO(playmobil): In the Windows version of this function, an HTML - // representation of the bookmark is also added to the clipboard, to support - // drag and drop of web shortcuts. I don't think we need to do this on the - // Mac, but we should double check later on. - NSURL* nsurl = [NSURL URLWithString:url]; - - NSPasteboard* pb = GetPasteboard(); - // passing UTIs into the pasteboard methods is valid >= 10.5 - [pb addTypes:[NSArray arrayWithObjects:NSURLPboardType, - kUTTypeURLName, - nil] - owner:nil]; - [nsurl writeToPasteboard:pb]; - [pb setString:title forType:kUTTypeURLName]; -} - -void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { - const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); - - // Safe because the image goes away before the call returns. - base::mac::ScopedCFTypeRef<CFDataRef> data( - CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - reinterpret_cast<const UInt8*>(pixel_data), - size->width()*size->height()*4, - kCFAllocatorNull)); - - base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( - CGDataProviderCreateWithCFData(data)); - - base::mac::ScopedCFTypeRef<CGImageRef> cgimage( - CGImageCreate(size->width(), - size->height(), - 8, - 32, - size->width()*4, - base::mac::GetSRGBColorSpace(), // TODO(avi): do better - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, - data_provider, - NULL, - false, - kCGRenderingIntentDefault)); - // Aggressively free storage since image buffers can potentially be very - // large. - data_provider.reset(); - data.reset(); - - scoped_nsobject<NSBitmapImageRep> bitmap( - [[NSBitmapImageRep alloc] initWithCGImage:cgimage]); - cgimage.reset(); - - scoped_nsobject<NSImage> image([[NSImage alloc] init]); - [image addRepresentation:bitmap]; - - // An API to ask the NSImage to write itself to the clipboard comes in 10.6 :( - // For now, spit out the image as a TIFF. - NSPasteboard* pb = GetPasteboard(); - [pb addTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil]; - NSData *tiff_data = [image TIFFRepresentation]; - LOG_IF(ERROR, tiff_data == NULL) << "Failed to allocate image for clipboard"; - if (tiff_data) { - [pb setData:tiff_data forType:NSTIFFPboardType]; - } -} - -// Write an extra flavor that signifies WebKit was the last to modify the -// pasteboard. This flavor has no data. -void Clipboard::WriteWebSmartPaste() { - NSPasteboard* pb = GetPasteboard(); - NSString* format = base::SysUTF8ToNSString(GetWebKitSmartPasteFormatType()); - [pb addTypes:[NSArray arrayWithObject:format] owner:nil]; - [pb setData:nil forType:format]; -} - -bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, - Clipboard::Buffer buffer) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - NSString* format_ns = base::SysUTF8ToNSString(format); - - NSPasteboard* pb = GetPasteboard(); - NSArray* types = [pb types]; - - // Safari only places RTF on the pasteboard, never HTML. We can convert RTF - // to HTML, so the presence of either indicates success when looking for HTML. - if ([format_ns isEqualToString:NSHTMLPboardType]) { - return [types containsObject:NSHTMLPboardType] || - [types containsObject:NSRTFPboardType]; - } - return [types containsObject:format_ns]; -} - -void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - NSPasteboard* pb = GetPasteboard(); - NSString* contents = [pb stringForType:NSStringPboardType]; - - UTF8ToUTF16([contents UTF8String], - [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], - result); -} - -void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, - std::string* result) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - NSPasteboard* pb = GetPasteboard(); - NSString* contents = [pb stringForType:NSStringPboardType]; - - if (!contents) - result->clear(); - else - result->assign([contents UTF8String]); -} - -void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, - std::string* src_url) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - if (markup) { - NSPasteboard* pb = GetPasteboard(); - NSArray* supportedTypes = [NSArray arrayWithObjects:NSHTMLPboardType, - NSRTFPboardType, - NSStringPboardType, - nil]; - NSString* bestType = [pb availableTypeFromArray:supportedTypes]; - NSString* contents = [pb stringForType:bestType]; - if ([bestType isEqualToString:NSRTFPboardType]) - contents = [pb htmlFromRtf]; - UTF8ToUTF16([contents UTF8String], - [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], - markup); - } - - // TODO(avi): src_url? - if (src_url) - src_url->clear(); -} - -void Clipboard::ReadBookmark(string16* title, std::string* url) const { - NSPasteboard* pb = GetPasteboard(); - - if (title) { - NSString* contents = [pb stringForType:kUTTypeURLName]; - UTF8ToUTF16([contents UTF8String], - [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], - title); - } - - if (url) { - NSString* url_string = [[NSURL URLFromPasteboard:pb] absoluteString]; - if (!url_string) - url->clear(); - else - url->assign([url_string UTF8String]); - } -} - -void Clipboard::ReadFile(FilePath* file) const { - if (!file) { - NOTREACHED(); - return; - } - - *file = FilePath(); - std::vector<FilePath> files; - ReadFiles(&files); - - // Take the first file, if available. - if (!files.empty()) - *file = files[0]; -} - -void Clipboard::ReadFiles(std::vector<FilePath>* files) const { - if (!files) { - NOTREACHED(); - return; - } - - files->clear(); - - NSPasteboard* pb = GetPasteboard(); - NSArray* fileList = [pb propertyListForType:NSFilenamesPboardType]; - - for (unsigned int i = 0; i < [fileList count]; ++i) { - std::string file = [[fileList objectAtIndex:i] UTF8String]; - files->push_back(FilePath(file)); - } -} - -// static -Clipboard::FormatType Clipboard::GetUrlFormatType() { - static const std::string type = base::SysNSStringToUTF8(NSURLPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetUrlWFormatType() { - static const std::string type = base::SysNSStringToUTF8(NSURLPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetPlainTextFormatType() { - static const std::string type = base::SysNSStringToUTF8(NSStringPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { - static const std::string type = base::SysNSStringToUTF8(NSStringPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetFilenameFormatType() { - static const std::string type = - base::SysNSStringToUTF8(NSFilenamesPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetFilenameWFormatType() { - static const std::string type = - base::SysNSStringToUTF8(NSFilenamesPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetHtmlFormatType() { - static const std::string type = base::SysNSStringToUTF8(NSHTMLPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetBitmapFormatType() { - static const std::string type = base::SysNSStringToUTF8(NSTIFFPboardType); - return type; -} - -// static -Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { - static const std::string type = - base::SysNSStringToUTF8(kWebSmartPastePboardType); - return type; -} diff --git a/app/clipboard/clipboard_unittest.cc b/app/clipboard/clipboard_unittest.cc deleted file mode 100644 index 28056d4..0000000 --- a/app/clipboard/clipboard_unittest.cc +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright (c) 2010 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. - -#include "build/build_config.h" - -#include <string> - -#include "app/clipboard/clipboard.h" -#include "app/clipboard/scoped_clipboard_writer.h" -#include "base/basictypes.h" -#include "base/scoped_ptr.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "gfx/size.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -#if defined(OS_WIN) -#include "app/clipboard/clipboard_util_win.h" -#include "base/message_loop.h" -#endif - -#if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX)) -#include "base/pickle.h" -#endif - -#if defined(OS_WIN) -class ClipboardTest : public PlatformTest { - protected: - virtual void SetUp() { - message_loop_.reset(new MessageLoopForUI()); - } - virtual void TearDown() { - } - - private: - scoped_ptr<MessageLoop> message_loop_; -}; -#elif defined(OS_POSIX) -typedef PlatformTest ClipboardTest; -#endif // defined(OS_WIN) - -namespace { - -bool ClipboardContentsIsExpected(const string16& copied_markup, - const string16& pasted_markup) { -#if defined(OS_POSIX) - return pasted_markup.find(copied_markup) != string16::npos; -#else - return copied_markup == pasted_markup; -#endif -} - -} // namespace - -TEST_F(ClipboardTest, ClearTest) { - Clipboard clipboard; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteText(ASCIIToUTF16("clear me")); - } - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteHTML(ASCIIToUTF16("<b>broom</b>"), ""); - } - - EXPECT_FALSE(clipboard.IsFormatAvailable( - Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD)); - EXPECT_FALSE(clipboard.IsFormatAvailable( - Clipboard::GetPlainTextFormatType(), Clipboard::BUFFER_STANDARD)); -} - -TEST_F(ClipboardTest, TextTest) { - Clipboard clipboard; - - string16 text(ASCIIToUTF16("This is a string16!#$")), text_result; - std::string ascii_text; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteText(text); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable( - Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD)); - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetPlainTextFormatType(), - Clipboard::BUFFER_STANDARD)); - clipboard.ReadText(Clipboard::BUFFER_STANDARD, &text_result); - - EXPECT_EQ(text, text_result); - clipboard.ReadAsciiText(Clipboard::BUFFER_STANDARD, &ascii_text); - EXPECT_EQ(UTF16ToUTF8(text), ascii_text); -} - -TEST_F(ClipboardTest, HTMLTest) { - Clipboard clipboard; - - string16 markup(ASCIIToUTF16("<string>Hi!</string>")), markup_result; - std::string url("http://www.example.com/"), url_result; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteHTML(markup, url); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType(), - Clipboard::BUFFER_STANDARD)); - clipboard.ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result); - EXPECT_TRUE(ClipboardContentsIsExpected(markup, markup_result)); -#if defined(OS_WIN) - // TODO(playmobil): It's not clear that non windows clipboards need to support - // this. - EXPECT_EQ(url, url_result); -#endif // defined(OS_WIN) -} - -TEST_F(ClipboardTest, TrickyHTMLTest) { - Clipboard clipboard; - - string16 markup(ASCIIToUTF16("<em>Bye!<!--EndFragment --></em>")), - markup_result; - std::string url, url_result; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteHTML(markup, url); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType(), - Clipboard::BUFFER_STANDARD)); - clipboard.ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result); - EXPECT_TRUE(ClipboardContentsIsExpected(markup, markup_result)); -#if defined(OS_WIN) - // TODO(playmobil): It's not clear that non windows clipboards need to support - // this. - EXPECT_EQ(url, url_result); -#endif // defined(OS_WIN) -} - -#if defined(OS_LINUX) -// Regression test for crbug.com/56298 (pasting empty HTML crashes Linux). -TEST_F(ClipboardTest, EmptyHTMLTest) { - Clipboard clipboard; - // ScopedClipboardWriter doesn't let us write empty data to the clipboard. - clipboard.clipboard_data_ = new Clipboard::TargetMap(); - // The 1 is so the compiler doesn't warn about allocating an empty array. - char* empty = new char[1]; - clipboard.InsertMapping("text/html", empty, 0U); - clipboard.SetGtkClipboard(); - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType(), - Clipboard::BUFFER_STANDARD)); - string16 markup_result; - std::string url_result; - clipboard.ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result); - EXPECT_TRUE(ClipboardContentsIsExpected(string16(), markup_result)); -} -#endif - -// TODO(estade): Port the following test (decide what target we use for urls) -#if !defined(OS_POSIX) || defined(OS_MACOSX) -TEST_F(ClipboardTest, BookmarkTest) { - Clipboard clipboard; - - string16 title(ASCIIToUTF16("The Example Company")), title_result; - std::string url("http://www.example.com/"), url_result; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteBookmark(title, url); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetUrlWFormatType(), - Clipboard::BUFFER_STANDARD)); - clipboard.ReadBookmark(&title_result, &url_result); - EXPECT_EQ(title, title_result); - EXPECT_EQ(url, url_result); -} -#endif // defined(OS_WIN) - -TEST_F(ClipboardTest, MultiFormatTest) { - Clipboard clipboard; - - string16 text(ASCIIToUTF16("Hi!")), text_result; - string16 markup(ASCIIToUTF16("<strong>Hi!</string>")), markup_result; - std::string url("http://www.example.com/"), url_result; - std::string ascii_text; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteHTML(markup, url); - clipboard_writer.WriteText(text); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType(), - Clipboard::BUFFER_STANDARD)); - EXPECT_TRUE(clipboard.IsFormatAvailable( - Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD)); - EXPECT_TRUE(clipboard.IsFormatAvailable( - Clipboard::GetPlainTextFormatType(), Clipboard::BUFFER_STANDARD)); - clipboard.ReadHTML(Clipboard::BUFFER_STANDARD, &markup_result, &url_result); - EXPECT_TRUE(ClipboardContentsIsExpected(markup, markup_result)); -#if defined(OS_WIN) - // TODO(playmobil): It's not clear that non windows clipboards need to support - // this. - EXPECT_EQ(url, url_result); -#endif // defined(OS_WIN) - clipboard.ReadText(Clipboard::BUFFER_STANDARD, &text_result); - EXPECT_EQ(text, text_result); - clipboard.ReadAsciiText(Clipboard::BUFFER_STANDARD, &ascii_text); - EXPECT_EQ(UTF16ToUTF8(text), ascii_text); -} - -TEST_F(ClipboardTest, URLTest) { - Clipboard clipboard; - - string16 url(ASCIIToUTF16("http://www.google.com/")); - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteURL(url); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable( - Clipboard::GetPlainTextWFormatType(), Clipboard::BUFFER_STANDARD)); - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetPlainTextFormatType(), - Clipboard::BUFFER_STANDARD)); - string16 text_result; - clipboard.ReadText(Clipboard::BUFFER_STANDARD, &text_result); - - EXPECT_EQ(text_result, url); - - std::string ascii_text; - clipboard.ReadAsciiText(Clipboard::BUFFER_STANDARD, &ascii_text); - EXPECT_EQ(UTF16ToUTF8(url), ascii_text); - -#if defined(OS_LINUX) - ascii_text.clear(); - clipboard.ReadAsciiText(Clipboard::BUFFER_SELECTION, &ascii_text); - EXPECT_EQ(UTF16ToUTF8(url), ascii_text); -#endif // defined(OS_LINUX) -} - -TEST_F(ClipboardTest, SharedBitmapTest) { - unsigned int fake_bitmap[] = { - 0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89, - 0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568, - 0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1, - }; - gfx::Size fake_bitmap_size(3, 4); - uint32 bytes = sizeof(fake_bitmap); - - // Create shared memory region. - base::SharedMemory shared_buf; - ASSERT_TRUE(shared_buf.CreateAndMapAnonymous(bytes)); - memcpy(shared_buf.memory(), fake_bitmap, bytes); - base::SharedMemoryHandle handle_to_share; - base::ProcessHandle current_process = base::kNullProcessHandle; -#if defined(OS_WIN) - current_process = GetCurrentProcess(); -#endif - shared_buf.ShareToProcess(current_process, &handle_to_share); - ASSERT_TRUE(shared_buf.Unmap()); - - // Setup data for clipboard. - Clipboard::ObjectMapParam placeholder_param; - Clipboard::ObjectMapParam size_param; - const char* size_data = reinterpret_cast<const char*>(&fake_bitmap_size); - for (size_t i = 0; i < sizeof(fake_bitmap_size); ++i) - size_param.push_back(size_data[i]); - - Clipboard::ObjectMapParams params; - params.push_back(placeholder_param); - params.push_back(size_param); - - Clipboard::ObjectMap objects; - objects[Clipboard::CBF_SMBITMAP] = params; - Clipboard::ReplaceSharedMemHandle(&objects, handle_to_share, current_process); - - Clipboard clipboard; - clipboard.WriteObjects(objects); - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetBitmapFormatType(), - Clipboard::BUFFER_STANDARD)); -} - -#if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX)) -TEST_F(ClipboardTest, DataTest) { - Clipboard clipboard; - const char* kFormat = "chromium/x-test-format"; - std::string payload("test string"); - Pickle write_pickle; - write_pickle.WriteString(payload); - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WritePickledData(write_pickle, kFormat); - } - - ASSERT_TRUE(clipboard.IsFormatAvailableByString( - kFormat, Clipboard::BUFFER_STANDARD)); - std::string output; - clipboard.ReadData(kFormat, &output); - ASSERT_FALSE(output.empty()); - - Pickle read_pickle(output.data(), output.size()); - void* iter = NULL; - std::string unpickled_string; - ASSERT_TRUE(read_pickle.ReadString(&iter, &unpickled_string)); - EXPECT_EQ(payload, unpickled_string); -} -#endif - -#if defined(OS_WIN) // Windows only tests. -TEST_F(ClipboardTest, HyperlinkTest) { - Clipboard clipboard; - - const std::string kTitle("The Example Company"); - const std::string kUrl("http://www.example.com/"); - const std::string kExpectedHtml("<a href=\"http://www.example.com/\">" - "The Example Company</a>"); - std::string url_result; - string16 html_result; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteHyperlink(ASCIIToUTF16(kTitle), kUrl); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetHtmlFormatType(), - Clipboard::BUFFER_STANDARD)); - clipboard.ReadHTML(Clipboard::BUFFER_STANDARD, &html_result, &url_result); - EXPECT_EQ(ASCIIToUTF16(kExpectedHtml), html_result); -} - -TEST_F(ClipboardTest, WebSmartPasteTest) { - Clipboard clipboard; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteWebSmartPaste(); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable( - Clipboard::GetWebKitSmartPasteFormatType(), Clipboard::BUFFER_STANDARD)); -} - -TEST_F(ClipboardTest, BitmapTest) { - unsigned int fake_bitmap[] = { - 0x46155189, 0xF6A55C8D, 0x79845674, 0xFA57BD89, - 0x78FD46AE, 0x87C64F5A, 0x36EDC5AF, 0x4378F568, - 0x91E9F63A, 0xC31EA14F, 0x69AB32DF, 0x643A3FD1, - }; - - Clipboard clipboard; - - { - ScopedClipboardWriter clipboard_writer(&clipboard); - clipboard_writer.WriteBitmapFromPixels(fake_bitmap, gfx::Size(3, 4)); - } - - EXPECT_TRUE(clipboard.IsFormatAvailable(Clipboard::GetBitmapFormatType(), - Clipboard::BUFFER_STANDARD)); -} - -void HtmlTestHelper(const std::string& cf_html, - const std::string& expected_html) { - std::string html; - ClipboardUtil::CFHtmlToHtml(cf_html, &html, NULL); - EXPECT_EQ(html, expected_html); -} - -TEST_F(ClipboardTest, HtmlTest) { - // Test converting from CF_HTML format data with <!--StartFragment--> and - // <!--EndFragment--> comments, like from MS Word. - HtmlTestHelper("Version:1.0\r\n" - "StartHTML:0000000105\r\n" - "EndHTML:0000000199\r\n" - "StartFragment:0000000123\r\n" - "EndFragment:0000000161\r\n" - "\r\n" - "<html>\r\n" - "<body>\r\n" - "<!--StartFragment-->\r\n" - "\r\n" - "<p>Foo</p>\r\n" - "\r\n" - "<!--EndFragment-->\r\n" - "</body>\r\n" - "</html>\r\n\r\n", - "<p>Foo</p>"); - - // Test converting from CF_HTML format data without <!--StartFragment--> and - // <!--EndFragment--> comments, like from OpenOffice Writer. - HtmlTestHelper("Version:1.0\r\n" - "StartHTML:0000000105\r\n" - "EndHTML:0000000151\r\n" - "StartFragment:0000000121\r\n" - "EndFragment:0000000131\r\n" - "<html>\r\n" - "<body>\r\n" - "<p>Foo</p>\r\n" - "</body>\r\n" - "</html>\r\n\r\n", - "<p>Foo</p>"); -} -#endif // defined(OS_WIN) - -// Test writing all formats we have simultaneously. -TEST_F(ClipboardTest, WriteEverything) { - Clipboard clipboard; - - { - ScopedClipboardWriter writer(&clipboard); - writer.WriteText(UTF8ToUTF16("foo")); - writer.WriteURL(UTF8ToUTF16("foo")); - writer.WriteHTML(UTF8ToUTF16("foo"), "bar"); - writer.WriteBookmark(UTF8ToUTF16("foo"), "bar"); - writer.WriteHyperlink(ASCIIToUTF16("foo"), "bar"); - writer.WriteWebSmartPaste(); - // Left out: WriteFile, WriteFiles, WriteBitmapFromPixels, WritePickledData. - } - - // Passes if we don't crash. -} diff --git a/app/clipboard/clipboard_util_win.cc b/app/clipboard/clipboard_util_win.cc deleted file mode 100644 index 3554002..0000000 --- a/app/clipboard/clipboard_util_win.cc +++ /dev/null @@ -1,540 +0,0 @@ -// Copyright (c) 2010 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. - -#include "app/clipboard/clipboard_util_win.h" - -#include <shellapi.h> -#include <shlwapi.h> -#include <wininet.h> // For INTERNET_MAX_URL_LENGTH. - -#include "base/basictypes.h" -#include "base/logging.h" -#include "base/scoped_handle.h" -#include "base/string_util.h" -#include "base/utf_string_conversions.h" -#include "base/win/scoped_hglobal.h" - -namespace { - -bool GetUrlFromHDrop(IDataObject* data_object, std::wstring* url, - std::wstring* title) { - DCHECK(data_object && url && title); - - STGMEDIUM medium; - if (FAILED(data_object->GetData(ClipboardUtil::GetCFHDropFormat(), &medium))) - return false; - - HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); - - if (!hdrop) - return false; - - bool success = false; - wchar_t filename[MAX_PATH]; - if (DragQueryFileW(hdrop, 0, filename, arraysize(filename))) { - wchar_t url_buffer[INTERNET_MAX_URL_LENGTH]; - if (0 == _wcsicmp(PathFindExtensionW(filename), L".url") && - GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, url_buffer, - arraysize(url_buffer), filename)) { - url->assign(url_buffer); - PathRemoveExtension(filename); - title->assign(PathFindFileName(filename)); - success = true; - } - } - - DragFinish(hdrop); - GlobalUnlock(medium.hGlobal); - // We don't need to call ReleaseStgMedium here because as far as I can tell, - // DragFinish frees the hGlobal for us. - return success; -} - -void SplitUrlAndTitle(const std::wstring& str, - std::wstring* url, - std::wstring* title) { - DCHECK(url && title); - size_t newline_pos = str.find('\n'); - if (newline_pos != std::wstring::npos) { - url->assign(str, 0, newline_pos); - title->assign(str, newline_pos + 1, std::wstring::npos); - } else { - url->assign(str); - title->assign(str); - } -} - -bool GetFileUrl(IDataObject* data_object, std::wstring* url, - std::wstring* title) { - STGMEDIUM store; - if (SUCCEEDED(data_object->GetData(ClipboardUtil::GetFilenameWFormat(), - &store))) { - bool success = false; - { - // filename using unicode - base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); - if (data.get() && data.get()[0] && - (PathFileExists(data.get()) || PathIsUNC(data.get()))) { - wchar_t file_url[INTERNET_MAX_URL_LENGTH]; - DWORD file_url_len = arraysize(file_url); - if (SUCCEEDED(::UrlCreateFromPathW(data.get(), file_url, &file_url_len, - 0))) { - url->assign(file_url); - title->assign(file_url); - success = true; - } - } - } - ReleaseStgMedium(&store); - if (success) - return true; - } - - if (SUCCEEDED(data_object->GetData(ClipboardUtil::GetFilenameFormat(), - &store))) { - bool success = false; - { - // filename using ascii - base::win::ScopedHGlobal<char> data(store.hGlobal); - if (data.get() && data.get()[0] && (PathFileExistsA(data.get()) || - PathIsUNCA(data.get()))) { - char file_url[INTERNET_MAX_URL_LENGTH]; - DWORD file_url_len = arraysize(file_url); - if (SUCCEEDED(::UrlCreateFromPathA(data.get(), file_url, &file_url_len, - 0))) { - url->assign(UTF8ToWide(file_url)); - title->assign(*url); - success = true; - } - } - } - ReleaseStgMedium(&store); - if (success) - return true; - } - return false; -} - -} // namespace - - -FORMATETC* ClipboardUtil::GetUrlFormat() { - static UINT cf = RegisterClipboardFormat(CFSTR_INETURLA); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetUrlWFormat() { - static UINT cf = RegisterClipboardFormat(CFSTR_INETURLW); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetMozUrlFormat() { - // The format is "URL\nTitle" - static UINT cf = RegisterClipboardFormat(L"text/x-moz-url"); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetPlainTextFormat() { - // We don't need to register this format since it's a built in format. - static FORMATETC format = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetPlainTextWFormat() { - // We don't need to register this format since it's a built in format. - static FORMATETC format = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, - TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetFilenameWFormat() { - static UINT cf = RegisterClipboardFormat(CFSTR_FILENAMEW); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetFilenameFormat() { - static UINT cf = RegisterClipboardFormat(CFSTR_FILENAMEA); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetHtmlFormat() { - static UINT cf = RegisterClipboardFormat(L"HTML Format"); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetTextHtmlFormat() { - static UINT cf = RegisterClipboardFormat(L"text/html"); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetCFHDropFormat() { - // We don't need to register this format since it's a built in format. - static FORMATETC format = {CF_HDROP, 0, DVASPECT_CONTENT, -1, - TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetFileDescriptorFormat() { - static UINT cf = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetFileContentFormatZero() { - static UINT cf = RegisterClipboardFormat(CFSTR_FILECONTENTS); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL}; - return &format; -} - -FORMATETC* ClipboardUtil::GetWebKitSmartPasteFormat() { - static UINT cf = RegisterClipboardFormat(L"WebKit Smart Paste Format"); - static FORMATETC format = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - return &format; -} - - -bool ClipboardUtil::HasUrl(IDataObject* data_object) { - DCHECK(data_object); - return SUCCEEDED(data_object->QueryGetData(GetMozUrlFormat())) || - SUCCEEDED(data_object->QueryGetData(GetUrlWFormat())) || - SUCCEEDED(data_object->QueryGetData(GetUrlFormat())) || - SUCCEEDED(data_object->QueryGetData(GetFilenameWFormat())) || - SUCCEEDED(data_object->QueryGetData(GetFilenameFormat())); -} - -bool ClipboardUtil::HasFilenames(IDataObject* data_object) { - DCHECK(data_object); - return SUCCEEDED(data_object->QueryGetData(GetCFHDropFormat())); -} - -bool ClipboardUtil::HasFileContents(IDataObject* data_object) { - DCHECK(data_object); - return SUCCEEDED(data_object->QueryGetData(GetFileContentFormatZero())); -} - -bool ClipboardUtil::HasHtml(IDataObject* data_object) { - DCHECK(data_object); - return SUCCEEDED(data_object->QueryGetData(GetHtmlFormat())) || - SUCCEEDED(data_object->QueryGetData(GetTextHtmlFormat())); -} - -bool ClipboardUtil::HasPlainText(IDataObject* data_object) { - DCHECK(data_object); - return SUCCEEDED(data_object->QueryGetData(GetPlainTextWFormat())) || - SUCCEEDED(data_object->QueryGetData(GetPlainTextFormat())); -} - - -bool ClipboardUtil::GetUrl(IDataObject* data_object, - std::wstring* url, std::wstring* title, bool convert_filenames) { - DCHECK(data_object && url && title); - if (!HasUrl(data_object)) - return false; - - // Try to extract a URL from |data_object| in a variety of formats. - STGMEDIUM store; - if (GetUrlFromHDrop(data_object, url, title)) - return true; - - if (SUCCEEDED(data_object->GetData(GetMozUrlFormat(), &store)) || - SUCCEEDED(data_object->GetData(GetUrlWFormat(), &store))) { - { - // Mozilla URL format or unicode URL - base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); - SplitUrlAndTitle(data.get(), url, title); - } - ReleaseStgMedium(&store); - return true; - } - - if (SUCCEEDED(data_object->GetData(GetUrlFormat(), &store))) { - { - // URL using ascii - base::win::ScopedHGlobal<char> data(store.hGlobal); - SplitUrlAndTitle(UTF8ToWide(data.get()), url, title); - } - ReleaseStgMedium(&store); - return true; - } - - if (convert_filenames) { - return GetFileUrl(data_object, url, title); - } else { - return false; - } -} - -bool ClipboardUtil::GetFilenames(IDataObject* data_object, - std::vector<std::wstring>* filenames) { - DCHECK(data_object && filenames); - if (!HasFilenames(data_object)) - return false; - - STGMEDIUM medium; - if (FAILED(data_object->GetData(GetCFHDropFormat(), &medium))) - return false; - - HDROP hdrop = static_cast<HDROP>(GlobalLock(medium.hGlobal)); - if (!hdrop) - return false; - - const int kMaxFilenameLen = 4096; - const unsigned num_files = DragQueryFileW(hdrop, 0xffffffff, 0, 0); - for (unsigned int i = 0; i < num_files; ++i) { - wchar_t filename[kMaxFilenameLen]; - if (!DragQueryFileW(hdrop, i, filename, kMaxFilenameLen)) - continue; - filenames->push_back(filename); - } - - DragFinish(hdrop); - GlobalUnlock(medium.hGlobal); - // We don't need to call ReleaseStgMedium here because as far as I can tell, - // DragFinish frees the hGlobal for us. - return true; -} - -bool ClipboardUtil::GetPlainText(IDataObject* data_object, - std::wstring* plain_text) { - DCHECK(data_object && plain_text); - if (!HasPlainText(data_object)) - return false; - - STGMEDIUM store; - if (SUCCEEDED(data_object->GetData(GetPlainTextWFormat(), &store))) { - { - // Unicode text - base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); - plain_text->assign(data.get()); - } - ReleaseStgMedium(&store); - return true; - } - - if (SUCCEEDED(data_object->GetData(GetPlainTextFormat(), &store))) { - { - // ascii text - base::win::ScopedHGlobal<char> data(store.hGlobal); - plain_text->assign(UTF8ToWide(data.get())); - } - ReleaseStgMedium(&store); - return true; - } - - // If a file is dropped on the window, it does not provide either of the - // plain text formats, so here we try to forcibly get a url. - std::wstring title; - return GetUrl(data_object, plain_text, &title, false); -} - -bool ClipboardUtil::GetHtml(IDataObject* data_object, - std::wstring* html, std::string* base_url) { - DCHECK(data_object && html && base_url); - - STGMEDIUM store; - if (SUCCEEDED(data_object->QueryGetData(GetHtmlFormat())) && - SUCCEEDED(data_object->GetData(GetHtmlFormat(), &store))) { - { - // MS CF html - base::win::ScopedHGlobal<char> data(store.hGlobal); - - std::string html_utf8; - CFHtmlToHtml(std::string(data.get(), data.Size()), &html_utf8, base_url); - html->assign(UTF8ToWide(html_utf8)); - } - ReleaseStgMedium(&store); - return true; - } - - if (FAILED(data_object->QueryGetData(GetTextHtmlFormat()))) - return false; - - if (FAILED(data_object->GetData(GetTextHtmlFormat(), &store))) - return false; - - { - // text/html - base::win::ScopedHGlobal<wchar_t> data(store.hGlobal); - html->assign(data.get()); - } - ReleaseStgMedium(&store); - return true; -} - -bool ClipboardUtil::GetFileContents(IDataObject* data_object, - std::wstring* filename, std::string* file_contents) { - DCHECK(data_object && filename && file_contents); - if (!SUCCEEDED(data_object->QueryGetData(GetFileContentFormatZero())) && - !SUCCEEDED(data_object->QueryGetData(GetFileDescriptorFormat()))) - return false; - - STGMEDIUM content; - // The call to GetData can be very slow depending on what is in - // |data_object|. - if (SUCCEEDED(data_object->GetData(GetFileContentFormatZero(), &content))) { - if (TYMED_HGLOBAL == content.tymed) { - base::win::ScopedHGlobal<char> data(content.hGlobal); - file_contents->assign(data.get(), data.Size()); - } - ReleaseStgMedium(&content); - } - - STGMEDIUM description; - if (SUCCEEDED(data_object->GetData(GetFileDescriptorFormat(), - &description))) { - { - base::win::ScopedHGlobal<FILEGROUPDESCRIPTOR> fgd(description.hGlobal); - // We expect there to be at least one file in here. - DCHECK_GE(fgd->cItems, 1u); - filename->assign(fgd->fgd[0].cFileName); - } - ReleaseStgMedium(&description); - } - return true; -} - -// HtmlToCFHtml and CFHtmlToHtml are based on similar methods in -// WebCore/platform/win/ClipboardUtilitiesWin.cpp. -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Helper method for converting from text/html to MS CF_HTML. -// Documentation for the CF_HTML format is available at -// http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx -std::string ClipboardUtil::HtmlToCFHtml(const std::string& html, - const std::string& base_url) { - if (html.empty()) - return std::string(); - - #define MAX_DIGITS 10 - #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits) - #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u" - #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS) - - static const char* header = "Version:0.9\r\n" - "StartHTML:" NUMBER_FORMAT "\r\n" - "EndHTML:" NUMBER_FORMAT "\r\n" - "StartFragment:" NUMBER_FORMAT "\r\n" - "EndFragment:" NUMBER_FORMAT "\r\n"; - static const char* source_url_prefix = "SourceURL:"; - - static const char* start_markup = - "<html>\r\n<body>\r\n<!--StartFragment-->\r\n"; - static const char* end_markup = - "\r\n<!--EndFragment-->\r\n</body>\r\n</html>"; - - // Calculate offsets - size_t start_html_offset = strlen(header) - strlen(NUMBER_FORMAT) * 4 + - MAX_DIGITS * 4; - if (!base_url.empty()) { - start_html_offset += strlen(source_url_prefix) + - base_url.length() + 2; // Add 2 for \r\n. - } - size_t start_fragment_offset = start_html_offset + strlen(start_markup); - size_t end_fragment_offset = start_fragment_offset + html.length(); - size_t end_html_offset = end_fragment_offset + strlen(end_markup); - - std::string result = StringPrintf(header, start_html_offset, - end_html_offset, start_fragment_offset, end_fragment_offset); - if (!base_url.empty()) { - result.append(source_url_prefix); - result.append(base_url); - result.append("\r\n"); - } - result.append(start_markup); - result.append(html); - result.append(end_markup); - - #undef MAX_DIGITS - #undef MAKE_NUMBER_FORMAT_1 - #undef MAKE_NUMBER_FORMAT_2 - #undef NUMBER_FORMAT - - return result; -} - -// Helper method for converting from MS CF_HTML to text/html. -void ClipboardUtil::CFHtmlToHtml(const std::string& cf_html, - std::string* html, - std::string* base_url) { - // Obtain base_url if present. - if (base_url) { - static std::string src_url_str("SourceURL:"); - size_t line_start = cf_html.find(src_url_str); - if (line_start != std::string::npos) { - size_t src_end = cf_html.find("\n", line_start); - size_t src_start = line_start + src_url_str.length(); - if (src_end != std::string::npos && src_start != std::string::npos) { - *base_url = cf_html.substr(src_start, src_end - src_start); - TrimWhitespace(*base_url, TRIM_ALL, base_url); - } - } - } - - // Find the markup between "<!--StartFragment-->" and "<!--EndFragment-->". - // If the comments cannot be found, like copying from OpenOffice Writer, - // we simply fall back to using StartFragment/EndFragment bytecount values - // to get the markup. - if (html) { - size_t fragment_start = std::string::npos; - size_t fragment_end = std::string::npos; - - std::string cf_html_lower = StringToLowerASCII(cf_html); - size_t markup_start = cf_html_lower.find("<html", 0); - size_t tag_start = cf_html.find("<!--StartFragment", markup_start); - if (tag_start == std::string::npos) { - static std::string start_fragment_str("StartFragment:"); - size_t start_fragment_start = cf_html.find(start_fragment_str); - if (start_fragment_start != std::string::npos) { - fragment_start = static_cast<size_t>(atoi(cf_html.c_str() + - start_fragment_start + start_fragment_str.length())); - } - - static std::string end_fragment_str("EndFragment:"); - size_t end_fragment_start = cf_html.find(end_fragment_str); - if (end_fragment_start != std::string::npos) { - fragment_end = static_cast<size_t>(atoi(cf_html.c_str() + - end_fragment_start + end_fragment_str.length())); - } - } else { - fragment_start = cf_html.find('>', tag_start) + 1; - size_t tag_end = cf_html.rfind("<!--EndFragment", std::string::npos); - fragment_end = cf_html.rfind('<', tag_end); - } - if (fragment_start != std::string::npos && - fragment_end != std::string::npos) { - *html = cf_html.substr(fragment_start, fragment_end - fragment_start); - TrimWhitespace(*html, TRIM_ALL, html); - } - } -} diff --git a/app/clipboard/clipboard_util_win.h b/app/clipboard/clipboard_util_win.h deleted file mode 100644 index 7283e33..0000000 --- a/app/clipboard/clipboard_util_win.h +++ /dev/null @@ -1,66 +0,0 @@ -// 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. -// -// Some helper functions for working with the clipboard and IDataObjects. - -#ifndef APP_CLIPBOARD_CLIPBOARD_UTIL_WIN_H_ -#define APP_CLIPBOARD_CLIPBOARD_UTIL_WIN_H_ -#pragma once - -#include <shlobj.h> -#include <string> -#include <vector> - -class ClipboardUtil { - public: - ///////////////////////////////////////////////////////////////////////////// - // Clipboard formats. - static FORMATETC* GetUrlFormat(); - static FORMATETC* GetUrlWFormat(); - static FORMATETC* GetMozUrlFormat(); - static FORMATETC* GetPlainTextFormat(); - static FORMATETC* GetPlainTextWFormat(); - static FORMATETC* GetFilenameFormat(); - static FORMATETC* GetFilenameWFormat(); - // MS HTML Format - static FORMATETC* GetHtmlFormat(); - // Firefox text/html - static FORMATETC* GetTextHtmlFormat(); - static FORMATETC* GetCFHDropFormat(); - static FORMATETC* GetFileDescriptorFormat(); - static FORMATETC* GetFileContentFormatZero(); - static FORMATETC* GetWebKitSmartPasteFormat(); - - ///////////////////////////////////////////////////////////////////////////// - // These methods check to see if |data_object| has the requested type. - // Returns true if it does. - static bool HasUrl(IDataObject* data_object); - static bool HasFilenames(IDataObject* data_object); - static bool HasPlainText(IDataObject* data_object); - static bool HasFileContents(IDataObject* data_object); - static bool HasHtml(IDataObject* data_object); - - ///////////////////////////////////////////////////////////////////////////// - // Helper methods to extract information from an IDataObject. These methods - // return true if the requested data type is found in |data_object|. - static bool GetUrl(IDataObject* data_object, - std::wstring* url, std::wstring* title, bool convert_filenames); - static bool GetFilenames(IDataObject* data_object, - std::vector<std::wstring>* filenames); - static bool GetPlainText(IDataObject* data_object, std::wstring* plain_text); - static bool GetHtml(IDataObject* data_object, std::wstring* text_html, - std::string* base_url); - static bool GetFileContents(IDataObject* data_object, - std::wstring* filename, - std::string* file_contents); - - // A helper method for converting between MS CF_HTML format and plain - // text/html. - static std::string HtmlToCFHtml(const std::string& html, - const std::string& base_url); - static void CFHtmlToHtml(const std::string& cf_html, std::string* html, - std::string* base_url); -}; - -#endif // APP_CLIPBOARD_CLIPBOARD_UTIL_WIN_H_ diff --git a/app/clipboard/clipboard_win.cc b/app/clipboard/clipboard_win.cc deleted file mode 100644 index 44dbb31..0000000 --- a/app/clipboard/clipboard_win.cc +++ /dev/null @@ -1,602 +0,0 @@ -// Copyright (c) 2010 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. - -// Many of these functions are based on those found in -// webkit/port/platform/PasteboardWin.cpp - -#include "app/clipboard/clipboard.h" - -#include <shlobj.h> -#include <shellapi.h> - -#include "app/clipboard/clipboard_util_win.h" -#include "base/file_path.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "base/shared_memory.h" -#include "base/string_util.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "gfx/size.h" - -namespace { - -// A scoper to manage acquiring and automatically releasing the clipboard. -class ScopedClipboard { - public: - ScopedClipboard() : opened_(false) { } - - ~ScopedClipboard() { - if (opened_) - Release(); - } - - bool Acquire(HWND owner) { - const int kMaxAttemptsToOpenClipboard = 5; - - if (opened_) { - NOTREACHED(); - return false; - } - - // Attempt to open the clipboard, which will acquire the Windows clipboard - // lock. This may fail if another process currently holds this lock. - // We're willing to try a few times in the hopes of acquiring it. - // - // This turns out to be an issue when using remote desktop because the - // rdpclip.exe process likes to read what we've written to the clipboard and - // send it to the RDP client. If we open and close the clipboard in quick - // succession, we might be trying to open it while rdpclip.exe has it open, - // See Bug 815425. - // - // In fact, we believe we'll only spin this loop over remote desktop. In - // normal situations, the user is initiating clipboard operations and there - // shouldn't be contention. - - for (int attempts = 0; attempts < kMaxAttemptsToOpenClipboard; ++attempts) { - // If we didn't manage to open the clipboard, sleep a bit and be hopeful. - if (attempts != 0) - ::Sleep(5); - - if (::OpenClipboard(owner)) { - opened_ = true; - return true; - } - } - - // We failed to acquire the clipboard. - return false; - } - - void Release() { - if (opened_) { - ::CloseClipboard(); - opened_ = false; - } else { - NOTREACHED(); - } - } - - private: - bool opened_; -}; - -LRESULT CALLBACK ClipboardOwnerWndProc(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam) { - LRESULT lresult = 0; - - switch (message) { - case WM_RENDERFORMAT: - // This message comes when SetClipboardData was sent a null data handle - // and now it's come time to put the data on the clipboard. - // We always set data, so there isn't a need to actually do anything here. - break; - case WM_RENDERALLFORMATS: - // This message comes when SetClipboardData was sent a null data handle - // and now this application is about to quit, so it must put data on - // the clipboard before it exits. - // We always set data, so there isn't a need to actually do anything here. - break; - case WM_DRAWCLIPBOARD: - break; - case WM_DESTROY: - break; - case WM_CHANGECBCHAIN: - break; - default: - lresult = DefWindowProc(hwnd, message, wparam, lparam); - break; - } - return lresult; -} - -template <typename charT> -HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) { - HGLOBAL data = - ::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT))); - if (data) { - charT* raw_data = static_cast<charT*>(::GlobalLock(data)); - memcpy(raw_data, str.data(), str.size() * sizeof(charT)); - raw_data[str.size()] = '\0'; - ::GlobalUnlock(data); - } - return data; -}; - -} // namespace - -Clipboard::Clipboard() : create_window_(false) { - if (MessageLoop::current()->type() == MessageLoop::TYPE_UI) { - // Make a dummy HWND to be the clipboard's owner. - WNDCLASSEX wcex = {0}; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.lpfnWndProc = ClipboardOwnerWndProc; - wcex.hInstance = GetModuleHandle(NULL); - wcex.lpszClassName = L"ClipboardOwnerWindowClass"; - ::RegisterClassEx(&wcex); - create_window_ = true; - } - - clipboard_owner_ = NULL; -} - -Clipboard::~Clipboard() { - if (clipboard_owner_) - ::DestroyWindow(clipboard_owner_); - clipboard_owner_ = NULL; -} - -void Clipboard::WriteObjects(const ObjectMap& objects) { - WriteObjects(objects, NULL); -} - -void Clipboard::WriteObjects(const ObjectMap& objects, - base::ProcessHandle process) { - ScopedClipboard clipboard; - if (!clipboard.Acquire(GetClipboardWindow())) - return; - - ::EmptyClipboard(); - - for (ObjectMap::const_iterator iter = objects.begin(); - iter != objects.end(); ++iter) { - DispatchObject(static_cast<ObjectType>(iter->first), iter->second); - } -} - -void Clipboard::WriteText(const char* text_data, size_t text_len) { - string16 text; - UTF8ToUTF16(text_data, text_len, &text); - HGLOBAL glob = CreateGlobalData(text); - - WriteToClipboard(CF_UNICODETEXT, glob); -} - -void Clipboard::WriteHTML(const char* markup_data, - size_t markup_len, - const char* url_data, - size_t url_len) { - std::string markup(markup_data, markup_len); - std::string url; - - if (url_len > 0) - url.assign(url_data, url_len); - - std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); - HGLOBAL glob = CreateGlobalData(html_fragment); - - WriteToClipboard(ClipboardUtil::GetHtmlFormat()->cfFormat, glob); -} - -void Clipboard::WriteBookmark(const char* title_data, - size_t title_len, - const char* url_data, - size_t url_len) { - std::string bookmark(title_data, title_len); - bookmark.append(1, L'\n'); - bookmark.append(url_data, url_len); - - string16 wide_bookmark = UTF8ToWide(bookmark); - HGLOBAL glob = CreateGlobalData(wide_bookmark); - - WriteToClipboard(ClipboardUtil::GetUrlWFormat()->cfFormat, glob); -} - -void Clipboard::WriteWebSmartPaste() { - DCHECK(clipboard_owner_); - ::SetClipboardData(ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat, - NULL); -} - -void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { - const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); - HDC dc = ::GetDC(NULL); - - // This doesn't actually cost us a memcpy when the bitmap comes from the - // renderer as we load it into the bitmap using setPixels which just sets a - // pointer. Someone has to memcpy it into GDI, it might as well be us here. - - // TODO(darin): share data in gfx/bitmap_header.cc somehow - BITMAPINFO bm_info = {0}; - bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bm_info.bmiHeader.biWidth = size->width(); - bm_info.bmiHeader.biHeight = -size->height(); // sets vertical orientation - bm_info.bmiHeader.biPlanes = 1; - bm_info.bmiHeader.biBitCount = 32; - bm_info.bmiHeader.biCompression = BI_RGB; - - // ::CreateDIBSection allocates memory for us to copy our bitmap into. - // Unfortunately, we can't write the created bitmap to the clipboard, - // (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx) - void *bits; - HBITMAP source_hbitmap = - ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0); - - if (bits && source_hbitmap) { - // Copy the bitmap out of shared memory and into GDI - memcpy(bits, pixel_data, 4 * size->width() * size->height()); - - // Now we have an HBITMAP, we can write it to the clipboard - WriteBitmapFromHandle(source_hbitmap, *size); - } - - ::DeleteObject(source_hbitmap); - ::ReleaseDC(NULL, dc); -} - -void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, - const gfx::Size& size) { - // We would like to just call ::SetClipboardData on the source_hbitmap, - // but that bitmap might not be of a sort we can write to the clipboard. - // For this reason, we create a new bitmap, copy the bits over, and then - // write that to the clipboard. - - HDC dc = ::GetDC(NULL); - HDC compatible_dc = ::CreateCompatibleDC(NULL); - HDC source_dc = ::CreateCompatibleDC(NULL); - - // This is the HBITMAP we will eventually write to the clipboard - HBITMAP hbitmap = ::CreateCompatibleBitmap(dc, size.width(), size.height()); - if (!hbitmap) { - // Failed to create the bitmap - ::DeleteDC(compatible_dc); - ::DeleteDC(source_dc); - ::ReleaseDC(NULL, dc); - return; - } - - HBITMAP old_hbitmap = (HBITMAP)SelectObject(compatible_dc, hbitmap); - HBITMAP old_source = (HBITMAP)SelectObject(source_dc, source_hbitmap); - - // Now we need to blend it into an HBITMAP we can place on the clipboard - BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; - ::GdiAlphaBlend(compatible_dc, 0, 0, size.width(), size.height(), - source_dc, 0, 0, size.width(), size.height(), bf); - - // Clean up all the handles we just opened - ::SelectObject(compatible_dc, old_hbitmap); - ::SelectObject(source_dc, old_source); - ::DeleteObject(old_hbitmap); - ::DeleteObject(old_source); - ::DeleteDC(compatible_dc); - ::DeleteDC(source_dc); - ::ReleaseDC(NULL, dc); - - WriteToClipboard(CF_BITMAP, hbitmap); -} - -void Clipboard::WriteData(const char* format_name, size_t format_len, - const char* data_data, size_t data_len) { - std::string format(format_name, format_len); - CLIPFORMAT clip_format = - ::RegisterClipboardFormat(ASCIIToWide(format).c_str()); - - HGLOBAL hdata = ::GlobalAlloc(GMEM_MOVEABLE, data_len); - if (!hdata) - return; - - char* data = static_cast<char*>(::GlobalLock(hdata)); - memcpy(data, data_data, data_len); - ::GlobalUnlock(data); - WriteToClipboard(clip_format, hdata); -} - -void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { - DCHECK(clipboard_owner_); - if (handle && !::SetClipboardData(format, handle)) { - DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); - FreeData(format, handle); - } -} - -bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, - Clipboard::Buffer buffer) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - int f; - if (!base::StringToInt(format, &f)) - return false; - return ::IsClipboardFormatAvailable(f) != FALSE; -} - -bool Clipboard::IsFormatAvailableByString( - const std::string& ascii_format, Clipboard::Buffer buffer) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - std::wstring wide_format = ASCIIToWide(ascii_format); - CLIPFORMAT format = ::RegisterClipboardFormat(wide_format.c_str()); - return ::IsClipboardFormatAvailable(format) != FALSE; -} - -void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - if (!result) { - NOTREACHED(); - return; - } - - result->clear(); - - // Acquire the clipboard. - ScopedClipboard clipboard; - if (!clipboard.Acquire(GetClipboardWindow())) - return; - - HANDLE data = ::GetClipboardData(CF_UNICODETEXT); - if (!data) - return; - - result->assign(static_cast<const char16*>(::GlobalLock(data))); - ::GlobalUnlock(data); -} - -void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, - std::string* result) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - if (!result) { - NOTREACHED(); - return; - } - - result->clear(); - - // Acquire the clipboard. - ScopedClipboard clipboard; - if (!clipboard.Acquire(GetClipboardWindow())) - return; - - HANDLE data = ::GetClipboardData(CF_TEXT); - if (!data) - return; - - result->assign(static_cast<const char*>(::GlobalLock(data))); - ::GlobalUnlock(data); -} - -void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, - std::string* src_url) const { - DCHECK_EQ(buffer, BUFFER_STANDARD); - if (markup) - markup->clear(); - - if (src_url) - src_url->clear(); - - // Acquire the clipboard. - ScopedClipboard clipboard; - if (!clipboard.Acquire(GetClipboardWindow())) - return; - - HANDLE data = ::GetClipboardData(ClipboardUtil::GetHtmlFormat()->cfFormat); - if (!data) - return; - - std::string html_fragment(static_cast<const char*>(::GlobalLock(data))); - ::GlobalUnlock(data); - - std::string markup_utf8; - ClipboardUtil::CFHtmlToHtml(html_fragment, markup ? &markup_utf8 : NULL, - src_url); - if (markup) - markup->assign(UTF8ToWide(markup_utf8)); -} - -void Clipboard::ReadBookmark(string16* title, std::string* url) const { - if (title) - title->clear(); - - if (url) - url->clear(); - - // Acquire the clipboard. - ScopedClipboard clipboard; - if (!clipboard.Acquire(GetClipboardWindow())) - return; - - HANDLE data = ::GetClipboardData(ClipboardUtil::GetUrlWFormat()->cfFormat); - if (!data) - return; - - string16 bookmark(static_cast<const char16*>(::GlobalLock(data))); - ::GlobalUnlock(data); - - ParseBookmarkClipboardFormat(bookmark, title, url); -} - -// Read a file in HDROP format from the clipboard. -void Clipboard::ReadFile(FilePath* file) const { - if (!file) { - NOTREACHED(); - return; - } - - *file = FilePath(); - std::vector<FilePath> files; - ReadFiles(&files); - - // Take the first file, if available. - if (!files.empty()) - *file = files[0]; -} - -// Read a set of files in HDROP format from the clipboard. -void Clipboard::ReadFiles(std::vector<FilePath>* files) const { - if (!files) { - NOTREACHED(); - return; - } - - files->clear(); - - ScopedClipboard clipboard; - if (!clipboard.Acquire(GetClipboardWindow())) - return; - - HDROP drop = static_cast<HDROP>(::GetClipboardData(CF_HDROP)); - if (!drop) - return; - - // Count of files in the HDROP. - int count = ::DragQueryFile(drop, 0xffffffff, NULL, 0); - - if (count) { - for (int i = 0; i < count; ++i) { - int size = ::DragQueryFile(drop, i, NULL, 0) + 1; - std::wstring file; - ::DragQueryFile(drop, i, WriteInto(&file, size), size); - files->push_back(FilePath(file)); - } - } -} - -void Clipboard::ReadData(const std::string& format, std::string* result) { - if (!result) { - NOTREACHED(); - return; - } - - CLIPFORMAT clip_format = - ::RegisterClipboardFormat(ASCIIToWide(format).c_str()); - - ScopedClipboard clipboard; - if (!clipboard.Acquire(GetClipboardWindow())) - return; - - HANDLE data = ::GetClipboardData(clip_format); - if (!data) - return; - - result->assign(static_cast<const char*>(::GlobalLock(data)), - ::GlobalSize(data)); - ::GlobalUnlock(data); -} - -// static -void Clipboard::ParseBookmarkClipboardFormat(const string16& bookmark, - string16* title, - std::string* url) { - const string16 kDelim = ASCIIToUTF16("\r\n"); - - const size_t title_end = bookmark.find_first_of(kDelim); - if (title) - title->assign(bookmark.substr(0, title_end)); - - if (url) { - const size_t url_start = bookmark.find_first_not_of(kDelim, title_end); - if (url_start != string16::npos) - *url = UTF16ToUTF8(bookmark.substr(url_start, string16::npos)); - } -} - -// static -Clipboard::FormatType Clipboard::GetUrlFormatType() { - return base::IntToString(ClipboardUtil::GetUrlFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetUrlWFormatType() { - return base::IntToString(ClipboardUtil::GetUrlWFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetMozUrlFormatType() { - return base::IntToString(ClipboardUtil::GetMozUrlFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetPlainTextFormatType() { - return base::IntToString(ClipboardUtil::GetPlainTextFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { - return base::IntToString(ClipboardUtil::GetPlainTextWFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetFilenameFormatType() { - return base::IntToString(ClipboardUtil::GetFilenameFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetFilenameWFormatType() { - return base::IntToString(ClipboardUtil::GetFilenameWFormat()->cfFormat); -} - -// MS HTML Format -// static -Clipboard::FormatType Clipboard::GetHtmlFormatType() { - return base::IntToString(ClipboardUtil::GetHtmlFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetBitmapFormatType() { - return base::IntToString(CF_BITMAP); -} - -// Firefox text/html -// static -Clipboard::FormatType Clipboard::GetTextHtmlFormatType() { - return base::IntToString(ClipboardUtil::GetTextHtmlFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetCFHDropFormatType() { - return base::IntToString(ClipboardUtil::GetCFHDropFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetFileDescriptorFormatType() { - return base::IntToString(ClipboardUtil::GetFileDescriptorFormat()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetFileContentFormatZeroType() { - return base::IntToString(ClipboardUtil::GetFileContentFormatZero()->cfFormat); -} - -// static -Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { - return base::IntToString( - ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat); -} - -// static -void Clipboard::FreeData(unsigned int format, HANDLE data) { - if (format == CF_BITMAP) - ::DeleteObject(static_cast<HBITMAP>(data)); - else - ::GlobalFree(data); -} - -HWND Clipboard::GetClipboardWindow() const { - if (!clipboard_owner_ && create_window_) { - clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", - L"ClipboardOwnerWindow", - 0, 0, 0, 0, 0, - HWND_MESSAGE, - 0, 0, 0); - } - return clipboard_owner_; -} diff --git a/app/clipboard/scoped_clipboard_writer.cc b/app/clipboard/scoped_clipboard_writer.cc deleted file mode 100644 index e2cb6ec..0000000 --- a/app/clipboard/scoped_clipboard_writer.cc +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2010 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. - -// This file implements the ScopedClipboardWriter class. Documentation on its -// purpose can be found in our header. Documentation on the format of the -// parameters for each clipboard target can be found in clipboard.h. - -#include "app/clipboard/scoped_clipboard_writer.h" - -#include "base/pickle.h" -#include "base/utf_string_conversions.h" -#include "gfx/size.h" - -ScopedClipboardWriter::ScopedClipboardWriter(Clipboard* clipboard) - : clipboard_(clipboard) { -} - -ScopedClipboardWriter::~ScopedClipboardWriter() { - if (!objects_.empty() && clipboard_) { - clipboard_->WriteObjects(objects_); - if (url_text_.length()) - clipboard_->DidWriteURL(url_text_); - } -} - -void ScopedClipboardWriter::WriteText(const string16& text) { - WriteTextOrURL(text, false); -} - -void ScopedClipboardWriter::WriteURL(const string16& text) { - WriteTextOrURL(text, true); -} - -void ScopedClipboardWriter::WriteHTML(const string16& markup, - const std::string& source_url) { - if (markup.empty()) - return; - - std::string utf8_markup = UTF16ToUTF8(markup); - - Clipboard::ObjectMapParams parameters; - parameters.push_back( - Clipboard::ObjectMapParam(utf8_markup.begin(), - utf8_markup.end())); - if (!source_url.empty()) { - parameters.push_back(Clipboard::ObjectMapParam(source_url.begin(), - source_url.end())); - } - - objects_[Clipboard::CBF_HTML] = parameters; -} - -void ScopedClipboardWriter::WriteBookmark(const string16& bookmark_title, - const std::string& url) { - if (bookmark_title.empty() || url.empty()) - return; - - std::string utf8_markup = UTF16ToUTF8(bookmark_title); - - Clipboard::ObjectMapParams parameters; - parameters.push_back(Clipboard::ObjectMapParam(utf8_markup.begin(), - utf8_markup.end())); - parameters.push_back(Clipboard::ObjectMapParam(url.begin(), url.end())); - objects_[Clipboard::CBF_BOOKMARK] = parameters; -} - -void ScopedClipboardWriter::WriteHyperlink(const string16& anchor_text, - const std::string& url) { - if (anchor_text.empty() || url.empty()) - return; - - // Construct the hyperlink. - std::string html("<a href=\""); - html.append(url); - html.append("\">"); - html.append(UTF16ToUTF8(anchor_text)); - html.append("</a>"); - WriteHTML(UTF8ToUTF16(html), std::string()); -} - -void ScopedClipboardWriter::WriteWebSmartPaste() { - objects_[Clipboard::CBF_WEBKIT] = Clipboard::ObjectMapParams(); -} - -void ScopedClipboardWriter::WriteBitmapFromPixels(const void* pixels, - const gfx::Size& size) { - Clipboard::ObjectMapParam pixels_parameter, size_parameter; - const char* pixels_data = reinterpret_cast<const char*>(pixels); - size_t pixels_length = 4 * size.width() * size.height(); - for (size_t i = 0; i < pixels_length; i++) - pixels_parameter.push_back(pixels_data[i]); - - const char* size_data = reinterpret_cast<const char*>(&size); - size_t size_length = sizeof(gfx::Size); - for (size_t i = 0; i < size_length; i++) - size_parameter.push_back(size_data[i]); - - Clipboard::ObjectMapParams parameters; - parameters.push_back(pixels_parameter); - parameters.push_back(size_parameter); - objects_[Clipboard::CBF_BITMAP] = parameters; -} - -void ScopedClipboardWriter::WritePickledData(const Pickle& pickle, - Clipboard::FormatType format) { - Clipboard::ObjectMapParam format_parameter(format.begin(), format.end()); - Clipboard::ObjectMapParam data_parameter; - - data_parameter.resize(pickle.size()); - memcpy(const_cast<char*>(&data_parameter.front()), - pickle.data(), pickle.size()); - - Clipboard::ObjectMapParams parameters; - parameters.push_back(format_parameter); - parameters.push_back(data_parameter); - objects_[Clipboard::CBF_DATA] = parameters; -} - -void ScopedClipboardWriter::WriteTextOrURL(const string16& text, bool is_url) { - if (text.empty()) - return; - - std::string utf8_text = UTF16ToUTF8(text); - - Clipboard::ObjectMapParams parameters; - parameters.push_back(Clipboard::ObjectMapParam(utf8_text.begin(), - utf8_text.end())); - objects_[Clipboard::CBF_TEXT] = parameters; - - if (is_url) { - url_text_ = utf8_text; - } else { - url_text_.clear(); - } -} diff --git a/app/clipboard/scoped_clipboard_writer.h b/app/clipboard/scoped_clipboard_writer.h deleted file mode 100644 index 61ef5b5..0000000 --- a/app/clipboard/scoped_clipboard_writer.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2010 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. - -// This file declares the ScopedClipboardWriter class, a wrapper around -// the Clipboard class which simplifies writing data to the system clipboard. -// Upon deletion the class atomically writes all data to |clipboard_|, -// avoiding any potential race condition with other processes that are also -// writing to the system clipboard. - -#ifndef APP_CLIPBOARD_SCOPED_CLIPBOARD_WRITER_H_ -#define APP_CLIPBOARD_SCOPED_CLIPBOARD_WRITER_H_ -#pragma once - -#include <string> - -#include "app/clipboard/clipboard.h" -#include "base/string16.h" - -class Pickle; - -// This class is a wrapper for |Clipboard| that handles packing data -// into a Clipboard::ObjectMap. -// NB: You should probably NOT be using this class if you include -// webkit_glue.h. Use ScopedClipboardWriterGlue instead. -class ScopedClipboardWriter { - public: - // Create an instance that is a simple wrapper around clipboard. - explicit ScopedClipboardWriter(Clipboard* clipboard); - - ~ScopedClipboardWriter(); - - // Converts |text| to UTF-8 and adds it to the clipboard. - void WriteText(const string16& text); - - // Converts the text of the URL to UTF-8 and adds it to the clipboard, then - // notifies the Clipboard that we just wrote a URL. - void WriteURL(const string16& text); - - // Adds HTML to the clipboard. The url parameter is optional, but especially - // useful if the HTML fragment contains relative links. - void WriteHTML(const string16& markup, const std::string& source_url); - - // Adds a bookmark to the clipboard. - void WriteBookmark(const string16& bookmark_title, - const std::string& url); - - // Adds an html hyperlink (<a href>) to the clipboard. |anchor_text| should - // be escaped prior to being passed in. - void WriteHyperlink(const string16& anchor_text, const std::string& url); - - // Used by WebKit to determine whether WebKit wrote the clipboard last - void WriteWebSmartPaste(); - - // Adds a bitmap to the clipboard - // Pixel format is assumed to be 32-bit BI_RGB. - void WriteBitmapFromPixels(const void* pixels, const gfx::Size& size); - - // Adds arbitrary data to clipboard. - void WritePickledData(const Pickle& pickle, Clipboard::FormatType format); - - protected: - // Converts |text| to UTF-8 and adds it to the clipboard. If it's a URL, we - // also notify the clipboard of that fact. - void WriteTextOrURL(const string16& text, bool is_url); - - // We accumulate the data passed to the various targets in the |objects_| - // vector, and pass it to Clipboard::WriteObjects() during object destruction. - Clipboard::ObjectMap objects_; - Clipboard* clipboard_; - - // We keep around the UTF-8 text of the URL in order to pass it to - // Clipboard::DidWriteURL(). - std::string url_text_; - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedClipboardWriter); -}; - -#endif // APP_CLIPBOARD_SCOPED_CLIPBOARD_WRITER_H_ diff --git a/app/os_exchange_data_provider_win.cc b/app/os_exchange_data_provider_win.cc index d6635ea..8dbd7e3 100644 --- a/app/os_exchange_data_provider_win.cc +++ b/app/os_exchange_data_provider_win.cc @@ -4,7 +4,6 @@ #include "app/os_exchange_data_provider_win.h" -#include "app/clipboard/clipboard_util_win.h" #include "app/l10n_util.h" #include "base/file_path.h" #include "base/i18n/file_util_icu.h" @@ -17,6 +16,9 @@ #include "googleurl/src/gurl.h" #include "grit/app_strings.h" #include "net/base/net_util.h" +#include "ui/base/clipboard/clipboard_util_win.h" + +using ui::ClipboardUtil; // Creates a new STGMEDIUM object to hold the specified text. The caller // owns the resulting object. The "Bytes" version does not NULL terminate, the diff --git a/app/os_exchange_data_win_unittest.cc b/app/os_exchange_data_win_unittest.cc index e76a52b..39fe2a6 100644 --- a/app/os_exchange_data_win_unittest.cc +++ b/app/os_exchange_data_win_unittest.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "app/clipboard/clipboard_util_win.h" #include "app/os_exchange_data.h" #include "app/os_exchange_data_provider_win.h" #include "base/pickle.h" @@ -13,6 +12,7 @@ #include "base/win/scoped_hglobal.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/clipboard/clipboard_util_win.h" typedef testing::Test OSExchangeDataTest; @@ -347,7 +347,7 @@ TEST(OSExchangeDataTest, Html) { STGMEDIUM medium; IDataObject* data_object = OSExchangeDataProviderWin::GetIDataObject(data); EXPECT_EQ(S_OK, - data_object->GetData(ClipboardUtil::GetHtmlFormat(), &medium)); + data_object->GetData(ui::ClipboardUtil::GetHtmlFormat(), &medium)); base::win::ScopedHGlobal<char> glob(medium.hGlobal); std::string output(glob.get(), glob.Size()); EXPECT_EQ(expected_cf_html, output); |