summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/clipboard_message_filter.cc63
-rw-r--r--content/browser/renderer_host/clipboard_message_filter.h3
-rw-r--r--content/common/clipboard_messages.h6
-rw-r--r--content/renderer/renderer_glue.cc11
-rw-r--r--ui/base/clipboard/clipboard_linux.cc19
5 files changed, 74 insertions, 28 deletions
diff --git a/content/browser/renderer_host/clipboard_message_filter.cc b/content/browser/renderer_host/clipboard_message_filter.cc
index 1b09839..65d2178 100644
--- a/content/browser/renderer_host/clipboard_message_filter.cc
+++ b/content/browser/renderer_host/clipboard_message_filter.cc
@@ -46,9 +46,7 @@ void ClipboardMessageFilter::OverrideThreadForMessage(
if (message.type() == ClipboardHostMsg_ReadImage::ID)
*thread = BrowserThread::FILE;
#elif defined(USE_X11)
- if (message.type() == ClipboardHostMsg_ReadImage::ID)
- *thread = BrowserThread::BACKGROUND_X11;
- else if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart)
+ if (IPC_MESSAGE_CLASS(message) == ClipboardMsgStart)
*thread = BrowserThread::UI;
#endif
}
@@ -65,7 +63,7 @@ bool ClipboardMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadText, OnReadText)
IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadAsciiText, OnReadAsciiText)
IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadHTML, OnReadHTML)
- IPC_MESSAGE_HANDLER(ClipboardHostMsg_ReadImage, OnReadImage)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ClipboardHostMsg_ReadImage, OnReadImage)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(ClipboardHostMsg_FindPboardWriteStringAsync,
OnFindPboardWriteString)
@@ -144,25 +142,48 @@ void ClipboardMessageFilter::OnReadHTML(
}
void ClipboardMessageFilter::OnReadImage(
- ui::Clipboard::Buffer buffer, std::string* data) {
+ ui::Clipboard::Buffer buffer, IPC::Message* reply_msg) {
SkBitmap bitmap = GetClipboard()->ReadImage(buffer);
- if (bitmap.isNull())
- return;
-
- std::vector<unsigned char> png_data;
- SkAutoLockPixels lock(bitmap);
- if (gfx::PNGCodec::EncodeWithCompressionLevel(
- static_cast<const unsigned char*>(bitmap.getPixels()),
- gfx::PNGCodec::FORMAT_BGRA,
- gfx::Size(bitmap.width(), bitmap.height()),
- bitmap.rowBytes(),
- false,
- std::vector<gfx::PNGCodec::Comment>(),
- Z_BEST_SPEED,
- &png_data)) {
- data->assign(reinterpret_cast<char*>(vector_as_array(&png_data)),
- png_data.size());
+
+#if defined(USE_X11)
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ this, &ClipboardMessageFilter::OnReadImageReply, bitmap, reply_msg));
+#else
+ OnReadImageReply(bitmap, reply_msg);
+#endif
+}
+
+void ClipboardMessageFilter::OnReadImageReply(
+ SkBitmap bitmap, IPC::Message* reply_msg) {
+ base::SharedMemoryHandle image_handle = base::SharedMemory::NULLHandle();
+ uint32 image_size = 0;
+ std::string reply_data;
+ if (!bitmap.isNull()) {
+ std::vector<unsigned char> png_data;
+ SkAutoLockPixels lock(bitmap);
+ if (gfx::PNGCodec::EncodeWithCompressionLevel(
+ static_cast<const unsigned char*>(bitmap.getPixels()),
+ gfx::PNGCodec::FORMAT_BGRA,
+ gfx::Size(bitmap.width(), bitmap.height()),
+ bitmap.rowBytes(),
+ false,
+ std::vector<gfx::PNGCodec::Comment>(),
+ Z_BEST_SPEED,
+ &png_data)) {
+ base::SharedMemory buffer;
+ if (buffer.CreateAndMapAnonymous(png_data.size())) {
+ memcpy(buffer.memory(), vector_as_array(&png_data), png_data.size());
+ if (buffer.GiveToProcess(peer_handle(), &image_handle)) {
+ image_size = png_data.size();
+ }
+ }
+ }
}
+ ClipboardHostMsg_ReadImage::WriteReplyParams(reply_msg, image_handle,
+ image_size);
+ Send(reply_msg);
}
void ClipboardMessageFilter::OnReadAvailableTypes(
diff --git a/content/browser/renderer_host/clipboard_message_filter.h b/content/browser/renderer_host/clipboard_message_filter.h
index b77a5a2..3128852 100644
--- a/content/browser/renderer_host/clipboard_message_filter.h
+++ b/content/browser/renderer_host/clipboard_message_filter.h
@@ -38,7 +38,8 @@ class ClipboardMessageFilter : public BrowserMessageFilter {
void OnReadText(ui::Clipboard::Buffer buffer, string16* result);
void OnReadAsciiText(ui::Clipboard::Buffer buffer, std::string* result);
void OnReadHTML(ui::Clipboard::Buffer buffer, string16* markup, GURL* url);
- void OnReadImage(ui::Clipboard::Buffer buffer, std::string* data);
+ void OnReadImage(ui::Clipboard::Buffer buffer, IPC::Message* reply_msg);
+ void OnReadImageReply(SkBitmap bitmap, IPC::Message* reply_msg);
#if defined(OS_MACOSX)
void OnFindPboardWriteString(const string16& text);
#endif
diff --git a/content/common/clipboard_messages.h b/content/common/clipboard_messages.h
index 7fe14af..5b06d2f 100644
--- a/content/common/clipboard_messages.h
+++ b/content/common/clipboard_messages.h
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+#include "base/shared_memory.h"
#include "content/common/common_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
@@ -45,9 +46,10 @@ IPC_SYNC_MESSAGE_CONTROL1_2(ClipboardHostMsg_ReadHTML,
ui::Clipboard::Buffer /* buffer */,
string16 /* markup */,
GURL /* url */)
-IPC_SYNC_MESSAGE_CONTROL1_1(ClipboardHostMsg_ReadImage,
+IPC_SYNC_MESSAGE_CONTROL1_2(ClipboardHostMsg_ReadImage,
ui::Clipboard::Buffer /* buffer */,
- std::string /* PNG-encoded image */)
+ base::SharedMemoryHandle /* PNG-encoded image */,
+ uint32 /* image size */)
#if defined(OS_MACOSX)
IPC_MESSAGE_CONTROL1(ClipboardHostMsg_FindPboardWriteStringAsync,
string16 /* text */)
diff --git a/content/renderer/renderer_glue.cc b/content/renderer/renderer_glue.cc
index 60a8d47..5ad03fd 100644
--- a/content/renderer/renderer_glue.cc
+++ b/content/renderer/renderer_glue.cc
@@ -14,6 +14,7 @@
#include "base/command_line.h"
#include "base/memory/ref_counted.h"
+#include "base/shared_memory.h"
#include "base/string_util.h"
#include "content/common/clipboard_messages.h"
#include "content/common/content_switches.h"
@@ -168,7 +169,15 @@ void ClipboardReadHTML(ui::Clipboard::Buffer buffer, string16* markup,
}
void ClipboardReadImage(ui::Clipboard::Buffer buffer, std::string* data) {
- RenderThread::current()->Send(new ClipboardHostMsg_ReadImage(buffer, data));
+ base::SharedMemoryHandle image_handle;
+ uint32 image_size;
+ RenderThread::current()->Send(
+ new ClipboardHostMsg_ReadImage(buffer, &image_handle, &image_size));
+ if (base::SharedMemory::IsHandleValid(image_handle)) {
+ base::SharedMemory buffer(image_handle, true);
+ buffer.Map(image_size);
+ data->append(static_cast<char*>(buffer.memory()), image_size);
+ }
}
bool ClipboardReadData(ui::Clipboard::Buffer buffer, const string16& type,
diff --git a/ui/base/clipboard/clipboard_linux.cc b/ui/base/clipboard/clipboard_linux.cc
index 3cbe7d8..883dcf5 100644
--- a/ui/base/clipboard/clipboard_linux.cc
+++ b/ui/base/clipboard/clipboard_linux.cc
@@ -15,6 +15,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/canvas_skia.h"
#include "ui/gfx/gtk_util.h"
#include "ui/gfx/size.h"
@@ -304,6 +305,8 @@ void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer,
types->push_back(UTF8ToUTF16(kMimeTypeText));
if (IsFormatAvailable(GetHtmlFormatType(), buffer))
types->push_back(UTF8ToUTF16(kMimeTypeHTML));
+ if (IsFormatAvailable(GetBitmapFormatType(), buffer))
+ types->push_back(UTF8ToUTF16(kMimeTypePNG));
*contains_filenames = false;
}
@@ -377,9 +380,19 @@ void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup,
}
SkBitmap Clipboard::ReadImage(Buffer buffer) const {
- // TODO(dcheng): implement this.
- NOTIMPLEMENTED();
- return SkBitmap();
+ ScopedGObject<GdkPixbuf>::Type pixbuf(
+ gtk_clipboard_wait_for_image(clipboard_));
+ if (!pixbuf.get())
+ return SkBitmap();
+
+ gfx::CanvasSkia canvas(gdk_pixbuf_get_width(pixbuf.get()),
+ gdk_pixbuf_get_height(pixbuf.get()),
+ false);
+ cairo_t* context = canvas.beginPlatformPaint();
+ gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0);
+ cairo_paint(context);
+ canvas.endPlatformPaint();
+ return canvas.ExtractBitmap();
}
void Clipboard::ReadBookmark(string16* title, std::string* url) const {