summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-25 19:45:59 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-25 19:45:59 +0000
commite4d8e1c51a06fee5e6c35d47feea83b1c7347dc4 (patch)
treebec7eff71b45f72059b0327ef7ea028204d340cc
parent63bb78db26ed509e9b12b586bafeb81f8bce40a5 (diff)
downloadchromium_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.cc2
-rw-r--r--base/clipboard_linux.cc29
-rw-r--r--base/scoped_clipboard_writer.cc2
-rw-r--r--base/scoped_clipboard_writer.h4
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc10
-rw-r--r--tools/gtk_clipboard_dump/gtk_clipboard_dump.cc6
-rw-r--r--webkit/glue/webclipboard_impl.cc2
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