summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-05 01:34:30 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-05 01:34:30 +0000
commit3ee3ffd1d79a0c1544f3bfd70c7de7606df9482f (patch)
tree0943a0925f5974478463e5d00886be29109858e6 /chrome
parent38733063b7e1cf0b6e67c0b590773ff4f1aaa18d (diff)
downloadchromium_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.cc8
-rw-r--r--chrome/browser/download/download_util.cc13
-rw-r--r--chrome/browser/render_view_context_menu_controller.cc5
-rw-r--r--chrome/browser/resource_message_filter.cc47
-rw-r--r--chrome/browser/resource_message_filter.h5
-rw-r--r--chrome/common/clipboard_service.cc20
-rw-r--r--chrome/common/clipboard_service.h14
-rw-r--r--chrome/common/common.vcproj4
-rw-r--r--chrome/common/render_messages_internal.h23
-rw-r--r--chrome/renderer/renderer_glue.cc119
-rw-r--r--chrome/views/text_field.cc7
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);
}
}