summaryrefslogtreecommitdiffstats
path: root/base/clipboard_linux.cc
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-07 01:22:22 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-07 01:22:22 +0000
commite4a41d8af760e10cd8d85ae877c9169f86ca6084 (patch)
treeaa384a871cca99389706994830a5aa5d86f7bf81 /base/clipboard_linux.cc
parent7a69c1461163ab03dac93b8459ac6f71c6df4a44 (diff)
downloadchromium_src-e4a41d8af760e10cd8d85ae877c9169f86ca6084.zip
chromium_src-e4a41d8af760e10cd8d85ae877c9169f86ca6084.tar.gz
chromium_src-e4a41d8af760e10cd8d85ae877c9169f86ca6084.tar.bz2
Linux: store clipboard image as bmp rather than converting to PNG.
Review URL: http://codereview.chromium.org/63040 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13218 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/clipboard_linux.cc')
-rw-r--r--base/clipboard_linux.cc67
1 files changed, 41 insertions, 26 deletions
diff --git a/base/clipboard_linux.cc b/base/clipboard_linux.cc
index 26228ad..4d52038 100644
--- a/base/clipboard_linux.cc
+++ b/base/clipboard_linux.cc
@@ -10,12 +10,12 @@
#include <string>
#include <utility>
-#include "base/gfx/png_encoder.h"
+#include "base/gfx/gtk_util.h"
#include "base/string_util.h"
namespace {
-const char* kMimePng = "image/png";
+const char* kMimeBmp = "image/bmp";
const char* kMimeHtml = "text/html";
const char* kMimeText = "text/plain";
const char* kMimeWebkitSmartPaste = "chromium-internal/webkit-paste";
@@ -40,15 +40,20 @@ void GetData(GtkClipboard* clipboard,
Clipboard::TargetMap* data_map =
reinterpret_cast<Clipboard::TargetMap*>(user_data);
- Clipboard::TargetMap::iterator iter =
- data_map->find(GdkAtomToString(selection_data->target));
+ std::string target_string = GdkAtomToString(selection_data->target);
+ Clipboard::TargetMap::iterator iter = data_map->find(target_string);
if (iter == data_map->end())
return;
- gtk_selection_data_set(selection_data, selection_data->target, 8,
- reinterpret_cast<guchar*>(iter->second.first),
- iter->second.second);
+ if (target_string == kMimeBmp) {
+ gtk_selection_data_set_pixbuf(selection_data,
+ reinterpret_cast<GdkPixbuf*>(iter->second.first));
+ } else {
+ gtk_selection_data_set(selection_data, selection_data->target, 8,
+ reinterpret_cast<guchar*>(iter->second.first),
+ iter->second.second);
+ }
}
// GtkClipboardClearFunc callback.
@@ -61,8 +66,12 @@ void ClearData(GtkClipboard* clipboard,
std::set<char*> ptrs;
for (Clipboard::TargetMap::iterator iter = map->begin();
- iter != map->end(); ++iter)
- ptrs.insert(iter->second.first);
+ iter != map->end(); ++iter) {
+ if (iter->first == kMimeBmp)
+ g_object_unref(reinterpret_cast<GdkPixbuf*>(iter->second.first));
+ else
+ ptrs.insert(iter->second.first);
+ }
for (std::set<char*>::iterator iter = ptrs.begin();
iter != ptrs.end(); ++iter)
@@ -87,6 +96,11 @@ void FreeTargetMap(Clipboard::TargetMap map) {
map.clear();
}
+// Called on GdkPixbuf destruction; see WriteBitmap().
+void GdkPixbufFree(guchar* pixels, gpointer data) {
+ free(pixels);
+}
+
} // namespace
Clipboard::Clipboard() {
@@ -161,24 +175,21 @@ 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) {
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());
+ int length = size->width() * size->height() * 4;
+ guchar* data = gfx::BGRAToRGBA(reinterpret_cast<const uint8_t*>(pixel_data),
+ size->width(), size->height(), 0);
+
+ GdkPixbuf* pixbuf =
+ gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE,
+ 8, size->width(), size->height(),
+ size->width() * 4, GdkPixbufFree, NULL);
+ // We store the GdkPixbuf*, and the size_t half of the pair is meaningless.
+ // Note that this contrasts with the vast majority of entries in our target
+ // map, which directly store the data and its length.
+ InsertMapping(kMimeBmp, reinterpret_cast<char*>(pixbuf), 0);
}
void Clipboard::WriteBookmark(const char* title_data, size_t title_len,
@@ -305,8 +316,12 @@ void Clipboard::InsertMapping(const char* key,
size_t data_len) {
TargetMap::iterator iter = clipboard_data_->find(key);
- if (iter != clipboard_data_->end())
- delete[] iter->second.first;
+ if (iter != clipboard_data_->end()) {
+ if (strcmp(kMimeBmp, key) == 0)
+ g_object_unref(reinterpret_cast<GdkPixbuf*>(iter->second.first));
+ else
+ delete[] iter->second.first;
+ }
(*clipboard_data_)[key] = std::make_pair(data, data_len);
}