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
Esse commit está contido em:
+1
-1
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_|
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário