diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-05 01:34:30 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-05 01:34:30 +0000 |
commit | 3ee3ffd1d79a0c1544f3bfd70c7de7606df9482f (patch) | |
tree | 0943a0925f5974478463e5d00886be29109858e6 /chrome | |
parent | 38733063b7e1cf0b6e67c0b590773ff4f1aaa18d (diff) | |
download | chromium_src-3ee3ffd1d79a0c1544f3bfd70c7de7606df9482f.zip chromium_src-3ee3ffd1d79a0c1544f3bfd70c7de7606df9482f.tar.gz chromium_src-3ee3ffd1d79a0c1544f3bfd70c7de7606df9482f.tar.bz2 |
Rewrote the clipboard API to be more concurrent. Added a helper class to make it more foolproof. Updated all clients and unittests. Mac port by jeremy@chromium.org
Review URL: http://codereview.chromium.org/9154
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4719 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit.cc | 8 | ||||
-rw-r--r-- | chrome/browser/download/download_util.cc | 13 | ||||
-rw-r--r-- | chrome/browser/render_view_context_menu_controller.cc | 5 | ||||
-rw-r--r-- | chrome/browser/resource_message_filter.cc | 47 | ||||
-rw-r--r-- | chrome/browser/resource_message_filter.h | 5 | ||||
-rw-r--r-- | chrome/common/clipboard_service.cc | 20 | ||||
-rw-r--r-- | chrome/common/clipboard_service.h | 14 | ||||
-rw-r--r-- | chrome/common/common.vcproj | 4 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 23 | ||||
-rw-r--r-- | chrome/renderer/renderer_glue.cc | 119 | ||||
-rw-r--r-- | chrome/views/text_field.cc | 7 |
11 files changed, 108 insertions, 157 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit.cc b/chrome/browser/autocomplete/autocomplete_edit.cc index 5974b81..fa60973 100644 --- a/chrome/browser/autocomplete/autocomplete_edit.cc +++ b/chrome/browser/autocomplete/autocomplete_edit.cc @@ -11,6 +11,7 @@ #include "base/gfx/skia_utils.h" #include "base/iat_patch.h" #include "base/ref_counted.h" +#include "base/scoped_clipboard_writer.h" #include "base/string_util.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/autocomplete/autocomplete_popup.h" @@ -1405,9 +1406,8 @@ void AutocompleteEditView::OnCopy() { if (text.empty()) return; - ClipboardService* clipboard = g_browser_process->clipboard_service(); - clipboard->Clear(); - clipboard->WriteText(text); + ScopedClipboardWriter scw(g_browser_process->clipboard_service()); + scw.WriteText(text); // Check if the user is copying the whole address bar. If they are, we // assume they are trying to copy a URL and write this to the clipboard as a @@ -1421,7 +1421,7 @@ void AutocompleteEditView::OnCopy() { // which will screw up our calculation of the desired_tld. GURL url; if (model_->GetURLForText(text, &url)) - clipboard->WriteHyperlink(text, url.spec()); + scw.WriteHyperlink(text, url.spec()); } void AutocompleteEditView::OnCut() { diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index f9040b3..262c507 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -10,6 +10,7 @@ #include "base/base_drag_source.h" #include "base/file_util.h" +#include "base/scoped_clipboard_writer.h" #include "base/gfx/image_operations.h" #include "base/string_util.h" #include "chrome/app/locales/locale_settings.h" @@ -105,24 +106,20 @@ bool BaseContextMenu::IsCommandEnabled(int id) const { } void BaseContextMenu::ExecuteCommand(int id) { - ClipboardService* clipboard = g_browser_process->clipboard_service(); - DCHECK(clipboard); + ScopedClipboardWriter scw(g_browser_process->clipboard_service()); switch (id) { case SHOW_IN_FOLDER: download_->manager()->ShowDownloadInShell(download_); break; case COPY_LINK: - clipboard->Clear(); - clipboard->WriteText(download_->url()); + scw.WriteText(download_->url()); break; case COPY_PATH: - clipboard->Clear(); - clipboard->WriteText(download_->full_path()); + scw.WriteText(download_->full_path()); break; case COPY_FILE: // TODO(paulg): Move to OSExchangeData when implementing drag and drop? - clipboard->Clear(); - clipboard->WriteFile(download_->full_path()); + scw.WriteFile(download_->full_path()); break; case OPEN_WHEN_COMPLETE: OpenDownload(download_); diff --git a/chrome/browser/render_view_context_menu_controller.cc b/chrome/browser/render_view_context_menu_controller.cc index f639b19..0e1b8f0 100644 --- a/chrome/browser/render_view_context_menu_controller.cc +++ b/chrome/browser/render_view_context_menu_controller.cc @@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/path_service.h" +#include "base/scoped_clipboard_writer.h" #include "base/string_util.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/common/chrome_paths.h" @@ -65,8 +66,8 @@ void RenderViewContextMenuController::WriteTextToClipboard( if (!clipboard) return; - clipboard->Clear(); - clipboard->WriteText(text); + ScopedClipboardWriter scw(clipboard); + scw.WriteText(text); } void RenderViewContextMenuController::WriteURLToClipboard(const GURL& url) { diff --git a/chrome/browser/resource_message_filter.cc b/chrome/browser/resource_message_filter.cc index 17c266b..2e25e92 100644 --- a/chrome/browser/resource_message_filter.cc +++ b/chrome/browser/resource_message_filter.cc @@ -4,6 +4,7 @@ #include "chrome/browser/resource_message_filter.h" +#include "base/clipboard.h" #include "base/histogram.h" #include "base/thread.h" #include "chrome/browser/chrome_plugin_browsing_context.h" @@ -125,22 +126,10 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewHostMsg_DnsPrefetch, OnDnsPrefetch) IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_PaintRect, render_widget_helper_->DidReceivePaintMsg(message)) - IPC_MESSAGE_FORWARD(ViewHostMsg_ClipboardClear, - static_cast<Clipboard*>(GetClipboardService()), - Clipboard::Clear) - IPC_MESSAGE_FORWARD(ViewHostMsg_ClipboardWriteText, - static_cast<Clipboard*>(GetClipboardService()), - Clipboard::WriteText) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteHTML, - OnClipboardWriteHTML) - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteBookmark, - OnClipboardWriteBookmark) - // We need to do more work to marshall around bitmaps - IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteBitmap, - OnClipboardWriteBitmap) - IPC_MESSAGE_FORWARD(ViewHostMsg_ClipboardWriteWebSmartPaste, - static_cast<Clipboard*>(GetClipboardService()), - Clipboard::WriteWebSmartPaste) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsAsync, + OnClipboardWriteObjects) + IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsSync, + OnClipboardWriteObjects) IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardIsFormatAvailable, OnClipboardIsFormatAvailable) IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadText, OnClipboardReadText) @@ -431,26 +420,12 @@ void ResourceMessageFilter::OnDownloadUrl(const IPC::Message& message, request_context_); } -void ResourceMessageFilter::OnClipboardWriteHTML(const std::wstring& markup, - const GURL& src_url) { - GetClipboardService()->WriteHTML(markup, src_url.spec()); -} - -void ResourceMessageFilter::OnClipboardWriteBookmark(const std::wstring& title, - const GURL& url) { - GetClipboardService()->WriteBookmark(title, url.spec()); -} - -void ResourceMessageFilter::OnClipboardWriteBitmap( - SharedMemoryHandle bitmap_buf, gfx::Size size) { - // hbitmap here is only valid in the context of the renderer. We need to - // import it into our process using SharedMemory in order to get a handle - // that is valid. - // - // We need to ask for write permission to the shared memory in order to - // call WriteBitmapFromSharedMemory - SharedMemory shared_mem(bitmap_buf, false, render_handle_); - GetClipboardService()->WriteBitmapFromSharedMemory(shared_mem, size); +void ResourceMessageFilter::OnClipboardWriteObjects( + const Clipboard::ObjectMap& objects) { + // We pass the render_handle_ to assist the clipboard with using shared + // memory objects. render_handle_ is a handle to the process that would + // own any shared memory that might be in the object list. + GetClipboardService()->WriteObjects(objects, render_handle_); } void ResourceMessageFilter::OnClipboardIsFormatAvailable(unsigned int format, diff --git a/chrome/browser/resource_message_filter.h b/chrome/browser/resource_message_filter.h index 1ac4c15..7dd3513 100644 --- a/chrome/browser/resource_message_filter.h +++ b/chrome/browser/resource_message_filter.h @@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_RENDERER_RESOURCE_MSG_FILTER_H__ #define CHROME_BROWSER_RENDERER_RESOURCE_MSG_FILTER_H__ +#include "base/clipboard.h" #include "base/gfx/rect.h" #include "base/gfx/native_widget_types.h" #include "base/ref_counted.h" @@ -121,9 +122,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, void OnDnsPrefetch(const std::vector<std::string>& hostnames); void OnReceiveContextMenuMsg(const IPC::Message& msg); // Clipboard messages - void OnClipboardWriteHTML(const std::wstring& markup, const GURL& src_url); - void OnClipboardWriteBookmark(const std::wstring& title, const GURL& url); - void OnClipboardWriteBitmap(SharedMemoryHandle bitmap, gfx::Size size); + void OnClipboardWriteObjects(const Clipboard::ObjectMap& objects); void OnClipboardIsFormatAvailable(unsigned int format, bool* result); void OnClipboardReadText(std::wstring* result); void OnClipboardReadAsciiText(std::string* result); diff --git a/chrome/common/clipboard_service.cc b/chrome/common/clipboard_service.cc deleted file mode 100644 index a666c0c..0000000 --- a/chrome/common/clipboard_service.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2006-2008 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 "chrome/common/clipboard_service.h" - -#include "SkBitmap.h" - -ClipboardService::ClipboardService() { -} - -void ClipboardService::WriteBitmap(const SkBitmap& bitmap) { - SkAutoLockPixels bitmap_lock(bitmap); - Clipboard::WriteBitmap(bitmap.getPixels(), - gfx::Size(bitmap.width(), bitmap.height())); -} - diff --git a/chrome/common/clipboard_service.h b/chrome/common/clipboard_service.h index 7da0e0a..ed34afd 100644 --- a/chrome/common/clipboard_service.h +++ b/chrome/common/clipboard_service.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_COMMON_CLIPBOARD_SERIVCE_H__ -#define CHROME_COMMON_CLIPBOARD_SERIVCE_H__ +#ifndef CHROME_COMMON_CLIPBOARD_SERVICE_H__ +#define CHROME_COMMON_CLIPBOARD_SERVICE_H__ #include <string> #include <vector> @@ -14,17 +14,11 @@ class SkBitmap; class ClipboardService : public Clipboard { public: - ClipboardService(); - - // Adds a bitmap to the clipboard - // This is the slowest way to copy a bitmap to the clipboard as we must fist - // memcpy the bits into GDI and the blit the bitmap to the clipboard. - void WriteBitmap(const SkBitmap& bitmap); + ClipboardService() {} private: DISALLOW_EVIL_CONSTRUCTORS(ClipboardService); }; -#endif // CHROME_COMMON_CLIPBOARD_SERIVCE_H__ - +#endif // CHROME_COMMON_CLIPBOARD_SERVICE_H__ diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj index 8bcb3ff..5359cfbd 100644 --- a/chrome/common/common.vcproj +++ b/chrome/common/common.vcproj @@ -390,10 +390,6 @@ > </File> <File - RelativePath=".\clipboard_service.cc" - > - </File> - <File RelativePath=".\clipboard_service.h" > </File> diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 61da8e7..ea97bc7 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/clipboard.h" #include "base/gfx/rect.h" #include "base/shared_memory.h" #include "chrome/common/ipc_message_macros.h" @@ -783,21 +784,15 @@ IPC_BEGIN_MESSAGES(ViewHost, 2) std::wstring /* plugin_path */) // Clipboard IPC messages - IPC_MESSAGE_CONTROL0(ViewHostMsg_ClipboardClear) - IPC_MESSAGE_CONTROL1(ViewHostMsg_ClipboardWriteText, - std::wstring /* text */) - IPC_MESSAGE_CONTROL2(ViewHostMsg_ClipboardWriteHTML, - std::wstring /* html */, - GURL /* url */) - IPC_MESSAGE_CONTROL2(ViewHostMsg_ClipboardWriteBookmark, - std::wstring /* title */, - GURL /* url */) - // This message is synchronized so that the renderer known when it is safe to + + // This message is used when the object list does not contain a bitmap. + IPC_MESSAGE_CONTROL1(ViewHostMsg_ClipboardWriteObjectsAsync, + Clipboard::ObjectMap /* objects */) + // This message is used when the object list contains a bitmap. + // It is synchronized so that the renderer knows when it is safe to // free the shared memory used to transfer the bitmap. - IPC_SYNC_MESSAGE_CONTROL2_0(ViewHostMsg_ClipboardWriteBitmap, - SharedMemoryHandle /* bitmap */, - gfx::Size /* size */) - IPC_MESSAGE_CONTROL0(ViewHostMsg_ClipboardWriteWebSmartPaste) + IPC_SYNC_MESSAGE_CONTROL1_0(ViewHostMsg_ClipboardWriteObjectsSync, + Clipboard::ObjectMap /* objects */) IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_ClipboardIsFormatAvailable, int /* format */, bool /* result */) diff --git a/chrome/renderer/renderer_glue.cc b/chrome/renderer/renderer_glue.cc index 83e5b95..297e5ac 100644 --- a/chrome/renderer/renderer_glue.cc +++ b/chrome/renderer/renderer_glue.cc @@ -7,6 +7,8 @@ #include <windows.h> #include <wininet.h> +#include "base/clipboard.h" +#include "base/scoped_clipboard_writer.h" #include "chrome/renderer/net/render_dns_master.h" #include "chrome/common/resource_bundle.h" #include "chrome/plugin/npobject_util.h" @@ -14,9 +16,12 @@ #include "chrome/renderer/visitedlink_slave.h" #include "googleurl/src/url_util.h" #include "net/base/mime_util.h" +#include "webkit/glue/scoped_clipboard_writer_glue.h" #include "webkit/glue/webframe.h" #include "webkit/glue/webkit_glue.h" +#include <vector> + #include "SkBitmap.h" #include <strsafe.h> // note: per msdn docs, this must *follow* other includes @@ -66,6 +71,66 @@ class ResizableStackArray { size_t cur_capacity_; }; +#if defined(OS_WIN) +// This definition of WriteBitmap uses shared memory to communicate across +// processes. +void ScopedClipboardWriterGlue::WriteBitmap(const SkBitmap& bitmap) { + // do not try to write a bitmap more than once + if (shared_buf_) + return; + + size_t buf_size = bitmap.getSize(); + gfx::Size size(bitmap.width(), bitmap.height()); + + // Allocate a shared memory buffer to hold the bitmap bits + shared_buf_ = RenderProcess::AllocSharedMemory(buf_size); + if (!shared_buf_ || !shared_buf_->Map(buf_size)) { + NOTREACHED(); + return; + } + + // Copy the bits into shared memory + SkAutoLockPixels bitmap_lock(bitmap); + memcpy(shared_buf_->memory(), bitmap.getPixels(), buf_size); + shared_buf_->Unmap(); + + Clipboard::ObjectMapParam param1, param2; + SharedMemoryHandle smh = shared_buf_->handle(); + + const char* shared_handle = reinterpret_cast<const char*>(&smh); + for (size_t i = 0; i < sizeof SharedMemoryHandle; i++) + param1.push_back(shared_handle[i]); + + const char* size_data = reinterpret_cast<const char*>(&size); + for (size_t i = 0; i < sizeof gfx::Size; i++) + param2.push_back(size_data[i]); + + Clipboard::ObjectMapParams params; + params.push_back(param1); + params.push_back(param2); + objects_[Clipboard::CBF_SMBITMAP] = params; +} +#endif + +// Define a destructor that makes IPCs to flush the contents to the +// system clipboard. +ScopedClipboardWriterGlue::~ScopedClipboardWriterGlue() { + if (objects_.empty()) + return; + +#if defined(OS_WIN) + if (shared_buf_) { + RenderThread::current()->Send( + new ViewHostMsg_ClipboardWriteObjectsSync(objects_)); + RenderProcess::FreeSharedMemory(shared_buf_); + return; + } +#endif + + RenderThread::current()->Send( + new ViewHostMsg_ClipboardWriteObjectsAsync(objects_)); +} + namespace webkit_glue { void PrefetchDns(const std::string& hostname) { @@ -141,58 +206,8 @@ HCURSOR webkit_glue::LoadCursor(int cursor_id) { // Clipboard glue -void webkit_glue::ClipboardClear() { - RenderThread::current()->Send(new ViewHostMsg_ClipboardClear()); -} - -void webkit_glue::ClipboardWriteText(const std::wstring& text) { - RenderThread::current()->Send(new ViewHostMsg_ClipboardWriteText(text)); -} - -void webkit_glue::ClipboardWriteHTML(const std::wstring& html, - const GURL& url) { - RenderThread::current()->Send(new ViewHostMsg_ClipboardWriteHTML(html, url)); -} - -void webkit_glue::ClipboardWriteBookmark(const std::wstring& title, - const GURL& url) { - RenderThread::current()->Send( - new ViewHostMsg_ClipboardWriteBookmark(title, url)); -} - -// Here we need to do some work to marshal the bitmap through shared memory -void webkit_glue::ClipboardWriteBitmap(const SkBitmap& bitmap) { - size_t buf_size = bitmap.getSize(); - gfx::Size size(bitmap.width(), bitmap.height()); - - // Allocate a shared memory buffer to hold the bitmap bits - SharedMemory* shared_buf = - RenderProcess::AllocSharedMemory(buf_size); - if (!shared_buf) { - NOTREACHED(); - return; - } - if (!shared_buf->Map(buf_size)) { - NOTREACHED(); - return; - } - - // Copy the bits into shared memory - SkAutoLockPixels bitmap_lock(bitmap); - memcpy(shared_buf->memory(), bitmap.getPixels(), buf_size); - shared_buf->Unmap(); - - // Send the handle over synchronous IPC - RenderThread::current()->Send( - new ViewHostMsg_ClipboardWriteBitmap(shared_buf->handle(), size)); - - // The browser should be done with the bitmap now. It's our job to free - // the shared memory. - RenderProcess::FreeSharedMemory(shared_buf); -} - -void webkit_glue::ClipboardWriteWebSmartPaste() { - RenderThread::current()->Send(new ViewHostMsg_ClipboardWriteWebSmartPaste()); +Clipboard* webkit_glue::ClipboardGetClipboard(){ + return NULL; } bool webkit_glue::ClipboardIsFormatAvailable(unsigned int format) { diff --git a/chrome/views/text_field.cc b/chrome/views/text_field.cc index baa70a1..c36fdbb 100644 --- a/chrome/views/text_field.cc +++ b/chrome/views/text_field.cc @@ -12,6 +12,7 @@ #include <vsstyle.h> #include "base/gfx/native_theme.h" +#include "base/scoped_clipboard_writer.h" #include "base/string_util.h" #include "base/win_util.h" #include "chrome/browser/browser_process.h" @@ -371,10 +372,8 @@ void TextField::Edit::OnCopy() { const std::wstring text(GetSelectedText()); if (!text.empty()) { - ClipboardService* clipboard = g_browser_process->clipboard_service(); - - clipboard->Clear(); - clipboard->WriteText(text); + ScopedClipboardWriter scw(g_browser_process->clipboard_service()); + scw.WriteText(text); } } |