diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-25 19:45:59 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-25 19:45:59 +0000 |
commit | e4d8e1c51a06fee5e6c35d47feea83b1c7347dc4 (patch) | |
tree | bec7eff71b45f72059b0327ef7ea028204d340cc | |
parent | 63bb78db26ed509e9b12b586bafeb81f8bce40a5 (diff) | |
download | chromium_src-e4d8e1c51a06fee5e6c35d47feea83b1c7347dc4.zip chromium_src-e4d8e1c51a06fee5e6c35d47feea83b1c7347dc4.tar.gz chromium_src-e4d8e1c51a06fee5e6c35d47feea83b1c7347dc4.tar.bz2 |
Linux: write images to clipboard.
Writing a bitmap to the clipboard is a rather slow operation, as it involves piping it over IPC and then converting it to a PNG.
Review URL: http://codereview.chromium.org/42592
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12482 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/clipboard.cc | 2 | ||||
-rw-r--r-- | base/clipboard_linux.cc | 29 | ||||
-rw-r--r-- | base/scoped_clipboard_writer.cc | 2 | ||||
-rw-r--r-- | base/scoped_clipboard_writer.h | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 10 | ||||
-rw-r--r-- | tools/gtk_clipboard_dump/gtk_clipboard_dump.cc | 6 | ||||
-rw-r--r-- | webkit/glue/webclipboard_impl.cc | 2 |
7 files changed, 37 insertions, 18 deletions
diff --git a/base/clipboard.cc b/base/clipboard.cc index 60851e2..8349b3d 100644 --- a/base/clipboard.cc +++ b/base/clipboard.cc @@ -38,7 +38,7 @@ void Clipboard::DispatchObject(ObjectType type, const ObjectMapParams& params) { WriteWebSmartPaste(); break; -#if defined(OS_WIN) || defined(OS_LINUX) // This is just a stub on Linux +#if defined(OS_WIN) || defined(OS_LINUX) case CBF_BITMAP: WriteBitmap(&(params[0].front()), &(params[1].front())); break; diff --git a/base/clipboard_linux.cc b/base/clipboard_linux.cc index 0f4bd36..26228ad 100644 --- a/base/clipboard_linux.cc +++ b/base/clipboard_linux.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/clipboard.h" -#include "base/string_util.h" #include <gtk/gtk.h> #include <map> @@ -11,11 +10,15 @@ #include <string> #include <utility> +#include "base/gfx/png_encoder.h" +#include "base/string_util.h" + namespace { -static const char* kMimeHtml = "text/html"; -static const char* kMimeText = "text/plain"; -static const char* kMimeWebkitSmartPaste = "chrome-internal/webkit-paste"; +const char* kMimePng = "image/png"; +const char* kMimeHtml = "text/html"; +const char* kMimeText = "text/plain"; +const char* kMimeWebkitSmartPaste = "chromium-internal/webkit-paste"; std::string GdkAtomToString(const GdkAtom& atom) { gchar* name = gdk_atom_name(atom); @@ -158,8 +161,24 @@ void Clipboard::WriteWebSmartPaste() { InsertMapping(kMimeWebkitSmartPaste, NULL, 0); } +// We have to convert the image to a PNG because gtk_clipboard_request_image() +// only works with PNGs. Warning: this is an internal implementation detail of +// gtk_clipboard_request_image() and might change in the future. void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { - NOTIMPLEMENTED(); + const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); + + std::vector<unsigned char> png_data; + if (!PNGEncoder::Encode( + reinterpret_cast<const unsigned char*>(pixel_data), + PNGEncoder::FORMAT_BGRA, size->width(), size->height(), + size->width() * 4, false, &png_data)) { + DLOG(ERROR) << "Failed to encode bitmap for clipboard."; + return; + } + char* data = new char[png_data.size()]; + memcpy(data, png_data.data(), png_data.size()); + + InsertMapping(kMimePng, data, png_data.size()); } void Clipboard::WriteBookmark(const char* title_data, size_t title_len, diff --git a/base/scoped_clipboard_writer.cc b/base/scoped_clipboard_writer.cc index 01335e4..9c74e6b 100644 --- a/base/scoped_clipboard_writer.cc +++ b/base/scoped_clipboard_writer.cc @@ -120,7 +120,6 @@ void ScopedClipboardWriter::WriteWebSmartPaste() { objects_[Clipboard::CBF_WEBKIT] = Clipboard::ObjectMapParams(); } -#if defined(OS_WIN) void ScopedClipboardWriter::WriteBitmapFromPixels(const void* pixels, const gfx::Size& size) { Clipboard::ObjectMapParam pixels_parameter, size_parameter; @@ -139,4 +138,3 @@ void ScopedClipboardWriter::WriteBitmapFromPixels(const void* pixels, parameters.push_back(size_parameter); objects_[Clipboard::CBF_BITMAP] = parameters; } -#endif // defined(OS_WIN) diff --git a/base/scoped_clipboard_writer.h b/base/scoped_clipboard_writer.h index 85eeacf2..03ac892 100644 --- a/base/scoped_clipboard_writer.h +++ b/base/scoped_clipboard_writer.h @@ -51,13 +51,9 @@ class ScopedClipboardWriter { // Used by WebKit to determine whether WebKit wrote the clipboard last void WriteWebSmartPaste(); -#if defined(OS_WIN) // Adds a bitmap to the clipboard - // This is the slowest way to copy a bitmap to the clipboard as we must first - // memcpy the pixels into GDI and the blit the bitmap to the clipboard. // Pixel format is assumed to be 32-bit BI_RGB. void WriteBitmapFromPixels(const void* pixels, const gfx::Size& size); -#endif // defined(OS_WIN) protected: // We accumulate the data passed to the various targets in the |objects_| diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 7d2b6d1..73f7154 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -499,13 +499,13 @@ void ResourceMessageFilter::OnClipboardWriteObjects( // a task to perform the write on the UI thread. Clipboard::ObjectMap* long_living_objects = new Clipboard::ObjectMap(objects); - // We pass the renderer handle to assist the clipboard with using shared - // memory objects. renderer handle is a handle to the process that would - // own any shared memory that might be in the object list. #if defined(OS_WIN) + // We pass the renderer handle to assist the clipboard with using shared + // memory objects. handle() is a handle to the process that would + // own any shared memory that might be in the object list. We only do this + // on Windows and it only applies to bitmaps. (On Linux, bitmaps + // are copied pixel by pixel rather than using shared memory.) Clipboard::DuplicateRemoteHandles(handle(), long_living_objects); -#else - NOTIMPLEMENTED(); // TODO(port) implement this. #endif render_widget_helper_->ui_loop()->PostTask(FROM_HERE, diff --git a/tools/gtk_clipboard_dump/gtk_clipboard_dump.cc b/tools/gtk_clipboard_dump/gtk_clipboard_dump.cc index 9d00ddb..e74cf8d 100644 --- a/tools/gtk_clipboard_dump/gtk_clipboard_dump.cc +++ b/tools/gtk_clipboard_dump/gtk_clipboard_dump.cc @@ -30,6 +30,12 @@ int main(int argc, char* argv[]) { } printf(" / length: %d / bits %d]: ", data->length, data->format); + + if (strstr(gdk_atom_name(targets[i]), "image")) { + printf("(image omitted)\n\n"); + continue; + } + for (int j = 0; j < data->length; j++) { // Output data one byte at a time. Currently wide strings look // pretty weird. diff --git a/webkit/glue/webclipboard_impl.cc b/webkit/glue/webclipboard_impl.cc index 5989c06..21674d2 100644 --- a/webkit/glue/webclipboard_impl.cc +++ b/webkit/glue/webclipboard_impl.cc @@ -119,7 +119,7 @@ void WebClipboardImpl::writeImage( const WebImage& image, const WebURL& url, const WebString& title) { ScopedClipboardWriterGlue scw(ClipboardGetClipboard()); -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) if (!image.isNull()) scw.WriteBitmapFromPixels(image.pixels(), image.size()); #endif |