diff options
-rw-r--r-- | content/browser/renderer_host/clipboard_message_filter.cc | 63 | ||||
-rw-r--r-- | content/browser/renderer_host/clipboard_message_filter.h | 3 | ||||
-rw-r--r-- | content/common/clipboard_messages.h | 6 | ||||
-rw-r--r-- | content/renderer/renderer_glue.cc | 11 | ||||
-rw-r--r-- | ui/base/clipboard/clipboard_linux.cc | 19 |
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 { |