15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/clipboard.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/extensions/Xfixes.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xatom.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/clipboard/custom_data_helper.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_signal.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/x/x11_util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_util.h" 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/scoped_gobject.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SelectionChangeObserver { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static SelectionChangeObserver* GetInstance(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 clipboard_sequence_number() const { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return clipboard_sequence_number_; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 primary_sequence_number() const { return primary_sequence_number_; } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct DefaultSingletonTraits<SelectionChangeObserver>; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionChangeObserver(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~SelectionChangeObserver(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHROMEG_CALLBACK_1(SelectionChangeObserver, GdkFilterReturn, OnXEvent, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkXEvent*, GdkEvent*); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int event_base_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Atom clipboard_atom_; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 clipboard_sequence_number_; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 primary_sequence_number_; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SelectionChangeObserver); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SelectionChangeObserver::SelectionChangeObserver() 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : event_base_(-1), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_atom_(None), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_sequence_number_(0), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_sequence_number_(0) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ignored; 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (XFixesQueryExtension(gfx::GetXDisplay(), &event_base_, &ignored)) { 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) clipboard_atom_ = XInternAtom(gfx::GetXDisplay(), "CLIPBOARD", false); 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XFixesSelectSelectionInput(gfx::GetXDisplay(), GetX11RootWindow(), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_atom_, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesSetSelectionOwnerNotifyMask | 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesSelectionWindowDestroyNotifyMask | 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesSelectionClientCloseNotifyMask); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This seems to be semi-optional. For some reason, registering for any 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // selection notify events seems to subscribe us to events for both the 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // primary and the clipboard buffers. Register anyway just to be safe. 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XFixesSelectSelectionInput(gfx::GetXDisplay(), GetX11RootWindow(), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XA_PRIMARY, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesSetSelectionOwnerNotifyMask | 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesSelectionWindowDestroyNotifyMask | 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesSelectionClientCloseNotifyMask); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_window_add_filter(NULL, &SelectionChangeObserver::OnXEventThunk, this); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SelectionChangeObserver::~SelectionChangeObserver() { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SelectionChangeObserver* SelectionChangeObserver::GetInstance() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<SelectionChangeObserver>::get(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkFilterReturn SelectionChangeObserver::OnXEvent(GdkXEvent* xevent, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkEvent* event) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XEvent* xev = static_cast<XEvent*>(xevent); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xev->type == event_base_ + XFixesSelectionNotify) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFixesSelectionNotifyEvent* ev = 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<XFixesSelectionNotifyEvent*>(xev); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->selection == clipboard_atom_) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_sequence_number_++; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ev->selection == XA_PRIMARY) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_sequence_number_++; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Unexpected selection atom: " << ev->selection; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GDK_FILTER_CONTINUE; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMimeTypeBitmap[] = "image/bmp"; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMimeTypeMozillaURL[] = "text/x-moz-url"; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data"; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GdkAtomToString(const GdkAtom& atom) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gchar* name = gdk_atom_name(atom); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string rv(name); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(name); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkAtom StringToGdkAtom(const std::string& str) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gdk_atom_intern(str.c_str(), FALSE); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GtkClipboardGetFunc callback. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GTK will call this when an application wants data we copied to the clipboard. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetData(GtkClipboard* clipboard, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* selection_data, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) guint info, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpointer user_data) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clipboard::TargetMap* data_map = 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<Clipboard::TargetMap*>(user_data); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string target_string = GdkAtomToString( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_target(selection_data)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clipboard::TargetMap::iterator iter = data_map->find(target_string); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == data_map->end()) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_string == kMimeTypeBitmap) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_set_pixbuf(selection_data, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<GdkPixbuf*>(iter->second.first)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_set(selection_data, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_target(selection_data), 8, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<guchar*>(iter->second.first), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second.second); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GtkClipboardClearFunc callback. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We are guaranteed this will be called exactly once for each call to 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gtk_clipboard_set_with_data. 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ClearData(GtkClipboard* /*clipboard*/, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpointer user_data) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clipboard::TargetMap* map = 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<Clipboard::TargetMap*>(user_data); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The same data may be inserted under multiple keys, so use a set to 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uniq them. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<char*> ptrs; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Clipboard::TargetMap::iterator iter = map->begin(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != map->end(); ++iter) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter->first == kMimeTypeBitmap) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_unref(reinterpret_cast<GdkPixbuf*>(iter->second.first)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptrs.insert(iter->second.first); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<char*>::iterator iter = ptrs.begin(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != ptrs.end(); ++iter) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete[] *iter; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete map; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::FormatType() : data_(GDK_NONE) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::FormatType(const std::string& format_string) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : data_(StringToGdkAtom(format_string)) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::FormatType(const GdkAtom& native_format) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : data_(native_format) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType::~FormatType() { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string Clipboard::FormatType::Serialize() const { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GdkAtomToString(data_); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType Clipboard::FormatType::Deserialize( 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& serialization) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FormatType(serialization); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Clipboard::FormatType::Equals(const FormatType& other) const { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_ == other.data_; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::Clipboard() : clipboard_data_(NULL) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::~Clipboard() { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_clipboard_store(clipboard_); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_data_ = new TargetMap(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ObjectMap::const_iterator iter = objects.begin(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != objects.end(); ++iter) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchObject(static_cast<ObjectType>(iter->first), iter->second); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetGtkClipboard(type); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (type == CLIPBOARD_TYPE_COPY_PASTE) { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectMap::const_iterator text_iter = objects.find(CBF_TEXT); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (text_iter != objects.end()) { 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Copy text and SourceTag to the selection clipboard. 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectMap::const_iterator next_iter = text_iter; 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WriteObjects(CLIPBOARD_TYPE_SELECTION, ObjectMap(text_iter, ++next_iter)); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Take ownership of the GTK clipboard and inform it of the targets we support. 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::SetGtkClipboard(ClipboardType type) { 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<GtkTargetEntry[]> targets( 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new GtkTargetEntry[clipboard_data_->size()]); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = 0; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Clipboard::TargetMap::iterator iter = clipboard_data_->begin(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != clipboard_data_->end(); ++iter, ++i) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targets[i].target = const_cast<char*>(iter->first.c_str()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targets[i].flags = 0; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targets[i].info = 0; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard *clipboard = LookupBackingClipboard(type); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gtk_clipboard_set_with_data(clipboard, targets.get(), 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_data_->size(), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetData, ClearData, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_data_)) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_clipboard_set_can_store(clipboard, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) targets.get(), 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_data_->size()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clipboard_data_ now owned by the GtkClipboard. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard_data_ = NULL; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteText(const char* text_data, size_t text_len) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data = new char[text_len]; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(data, text_data, text_len); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping(kMimeTypeText, data, text_len); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping("TEXT", data, text_len); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping("STRING", data, text_len); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping("UTF8_STRING", data, text_len); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping("COMPOUND_TEXT", data, text_len); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteHTML(const char* markup_data, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t markup_len, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t url_len) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(estade): We need to expand relative links with |url_data|. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* html_prefix = "<meta http-equiv=\"content-type\" " 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "content=\"text/html; charset=utf-8\">"; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t html_prefix_len = strlen(html_prefix); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t total_len = html_prefix_len + markup_len + 1; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data = new char[total_len]; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(data, total_len, "%s", html_prefix); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(data + html_prefix_len, markup_data, markup_len); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some programs expect NULL-terminated data. See http://crbug.com/42624 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data[total_len - 1] = '\0'; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping(kMimeTypeHTML, data, total_len); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteData(GetRtfFormatType(), rtf_data, data_len); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Write an extra flavor that signifies WebKit was the last to modify the 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pasteboard. This flavor has no data. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteWebSmartPaste() { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping(kMimeTypeWebkitSmartPaste, NULL, 0); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Clipboard::WriteBitmap(const SkBitmap& bitmap) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(bitmap); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We store the GdkPixbuf*, and the size_t half of the pair is meaningless. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this contrasts with the vast majority of entries in our target 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // map, which directly store the data and its length. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping(kMimeTypeBitmap, reinterpret_cast<char*>(pixbuf), 0); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteBookmark(const char* title_data, size_t title_len, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_data, size_t url_len) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write as a mozilla url (UTF16: URL, newline, title). 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 title = UTF8ToUTF16(std::string(title_data, title_len)); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (title.length() >= std::numeric_limits<size_t>::max() / 4 || 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url.length() >= std::numeric_limits<size_t>::max() / 4) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t data_len = 2 * (title.length() + url.length()); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data = new char[data_len]; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(data, url.data(), 2 * url.length()); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(data + 2 * url.length(), title.data(), 2 * title.length()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping(kMimeTypeMozillaURL, data, data_len); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::WriteData(const FormatType& format, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data_data, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t data_len) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We assume that certain mapping types are only written by trusted code. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Therefore we must upkeep their integrity. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format.Equals(GetBitmapFormatType())) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data = new char[data_len]; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(data, data_data, data_len); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(dcheng): Maybe this map should use GdkAtoms... 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertMapping(GdkAtomToString(format.ToGdkAtom()).c_str(), data, data_len); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We do not use gtk_clipboard_wait_is_target_available because of 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a bug with the gtk clipboard. It caches the available targets 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and does not always refresh the cache when it is appropriate. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, 3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ClipboardType type) const { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard* clipboard = LookupBackingClipboard(type); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (clipboard == NULL) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool retval = false; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* data = gtk_clipboard_wait_for_contents( 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard, gdk_atom_intern_static_string("TARGETS")); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool format_is_plain_text = GetPlainTextFormatType().Equals(format); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (format_is_plain_text) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This tries a number of common text targets. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = gtk_selection_data_targets_include_text(data); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some programs like Java decide to set an empty TARGETS list, so even if 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data is not NULL, we still have to fall back. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!retval) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some programs post data to the clipboard without any targets. If this 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is the case we attempt to make sense of the contents as text. This is 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pretty unfortunate since it means we have to actually copy the data to 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // see if it is available, but at least this path shouldn't be hit for 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // conforming programs. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gchar* text = gtk_clipboard_wait_for_text(clipboard); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(text); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (data) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkAtom* targets = NULL; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num = 0; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_targets(data, &targets, &num); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < num; i++) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (targets[i] == format.ToGdkAtom()) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retval = true; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(targets); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_free(data); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return retval; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::Clear(ClipboardType type) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard* clipboard = LookupBackingClipboard(type); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (clipboard == NULL) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_clipboard_clear(clipboard); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadAvailableTypes(ClipboardType type, 410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<base::string16>* types, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* contains_filenames) const { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!types || !contains_filenames) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->clear(); 4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsFormatAvailable(GetPlainTextFormatType(), type)) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeText)); 4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsFormatAvailable(GetHtmlFormatType(), type)) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeHTML)); 4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsFormatAvailable(GetRtfFormatType(), type)) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypeRTF)); 4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsFormatAvailable(GetBitmapFormatType(), type)) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types->push_back(UTF8ToUTF16(kMimeTypePNG)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contains_filenames = false; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard* clipboard = LookupBackingClipboard(type); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* data = gtk_clipboard_wait_for_contents( 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard, GetWebCustomDataFormatType().ToGdkAtom()); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadCustomDataTypes(gtk_selection_data_get_data(data), 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_length(data), 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_free(data); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void Clipboard::ReadText(ClipboardType type, base::string16* result) const { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard* clipboard = LookupBackingClipboard(type); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (clipboard == NULL) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->clear(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gchar* text = gtk_clipboard_wait_for_text(clipboard); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text == NULL) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(estade): do we want to handle the possible error here? 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF8ToUTF16(text, strlen(text), result); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(text); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadAsciiText(ClipboardType type, 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* result) const { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard* clipboard = LookupBackingClipboard(type); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (clipboard == NULL) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->clear(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gchar* text = gtk_clipboard_wait_for_text(clipboard); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text == NULL) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(text); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_free(text); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(estade): handle different charsets. 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(port): set *src_url. 4804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadHTML(ClipboardType type, 481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* markup, 4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string* src_url, 4834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32* fragment_start, 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* fragment_end) const { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markup->clear(); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (src_url) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) src_url->clear(); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_start = 0; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_end = 0; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard* clipboard = LookupBackingClipboard(type); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (clipboard == NULL) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetHtmlFormatType().ToGdkAtom()); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UTF-16, otherwise assume UTF-8. 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint data_length = gtk_selection_data_get_length(data); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const guchar* raw_data = gtk_selection_data_get_data(data); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_length >= 2 && 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const uint16_t*>(raw_data)[0] == 0xFEFF) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markup->assign(reinterpret_cast<const uint16_t*>(raw_data) + 1, 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (data_length / 2) - 1); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF8ToUTF16(reinterpret_cast<const char*>(raw_data), data_length, markup); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is a terminating NULL, drop it. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!markup->empty() && markup->at(markup->length() - 1) == '\0') 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markup->resize(markup->length() - 1); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_start = 0; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(markup->length() <= kuint32max); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *fragment_end = static_cast<uint32>(markup->length()); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_free(data); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadRTF(ClipboardType type, std::string* result) const { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadData(GetRtfFormatType(), result); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SkBitmap Clipboard::ReadImage(ClipboardType type) const { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedGObject<GdkPixbuf>::Type pixbuf( 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_clipboard_wait_for_image(clipboard_)); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pixbuf.get()) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SkBitmap(); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Canvas canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf.get()), 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_pixbuf_get_height(pixbuf.get())), 53968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1.0f, false); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_t* context = scoped_platform_paint.GetPlatformSurface(); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_paint(context); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return canvas.ExtractImageRep().sk_bitmap(); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Clipboard::ReadCustomData(ClipboardType clipboard_type, 550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& type, 551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* result) const { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GtkClipboard* clipboard = LookupBackingClipboard(clipboard_type); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!clipboard) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* data = gtk_clipboard_wait_for_contents( 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clipboard, GetWebCustomDataFormatType().ToGdkAtom()); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadCustomDataForType(gtk_selection_data_get_data(data), 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_length(data), 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, result); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_free(data); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void Clipboard::ReadBookmark(base::string16* title, std::string* url) const { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(estade): implement this. 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::ReadData(const FormatType& format, std::string* result) const { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->clear(); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GtkSelectionData* data = 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gtk_clipboard_wait_for_contents(clipboard_, format.ToGdkAtom()); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->assign(reinterpret_cast<const char*>( 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_data(data)), 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_get_length(data)); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_selection_data_free(data); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)uint64 Clipboard::GetSequenceNumber(ClipboardType type) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (type == CLIPBOARD_TYPE_COPY_PASTE) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SelectionChangeObserver::GetInstance()->primary_sequence_number(); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//static 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Clipboard::FormatType Clipboard::GetFormatType( 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& format_string) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FormatType::Deserialize(format_string); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL( 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatType, type, (GDK_TARGET_STRING)); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetPlainTextFormatType(); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetUrlFormatType() { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetPlainTextFormatType(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetUrlWFormatType() { 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetPlainTextWFormatType(); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetHtmlFormatType() { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeHTML)); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetRtfFormatType() { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeRTF)); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetBitmapFormatType() { 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeBitmap)); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebkitSmartPaste)); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData)); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Clipboard::InsertMapping(const char* key, 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data, 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t data_len) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(clipboard_data_->find(key) == clipboard_data_->end()); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*clipboard_data_)[key] = std::make_pair(data, data_len); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GtkClipboard* Clipboard::LookupBackingClipboard(ClipboardType type) const { 6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (type) { 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case CLIPBOARD_TYPE_COPY_PASTE: 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return clipboard_; 6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case CLIPBOARD_TYPE_SELECTION: 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return primary_selection_; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 677