| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "ui/base/clipboard/clipboard.h" |    5 #include "ui/base/clipboard/clipboard.h" | 
|    6  |    6  | 
|    7 #include <X11/extensions/Xfixes.h> |    7 #include <X11/extensions/Xfixes.h> | 
|    8 #include <X11/Xatom.h> |    8 #include <X11/Xatom.h> | 
|    9 #include <list> |    9 #include <list> | 
|   10 #include <set> |   10 #include <set> | 
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  232   X11AtomCache* atom_cache() { return &atom_cache_; } |  232   X11AtomCache* atom_cache() { return &atom_cache_; } | 
|  233  |  233  | 
|  234   // Returns the X11 type that we pass to various XSelection functions for the |  234   // Returns the X11 type that we pass to various XSelection functions for the | 
|  235   // given buffer. |  235   // given buffer. | 
|  236   ::Atom LookupSelectionForBuffer(Buffer buffer) const; |  236   ::Atom LookupSelectionForBuffer(Buffer buffer) const; | 
|  237  |  237  | 
|  238   // Returns the object which is responsible for communication on |buffer|. |  238   // Returns the object which is responsible for communication on |buffer|. | 
|  239   SelectionRequestor* GetSelectionRequestorForBuffer(Buffer buffer); |  239   SelectionRequestor* GetSelectionRequestorForBuffer(Buffer buffer); | 
|  240  |  240  | 
|  241   // Finds the SelectionFormatMap for the incoming selection atom. |  241   // Finds the SelectionFormatMap for the incoming selection atom. | 
|  242   SelectionFormatMap* LookupStorageForAtom(::Atom atom); |  242   const SelectionFormatMap& LookupStorageForAtom(::Atom atom); | 
|  243  |  243  | 
|  244   // As we need to collect all the data types before we tell X11 that we own a |  244   // As we need to collect all the data types before we tell X11 that we own a | 
|  245   // particular selection, we create a temporary clipboard mapping that |  245   // particular selection, we create a temporary clipboard mapping that | 
|  246   // InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection, |  246   // InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection, | 
|  247   // where we save it in one of the clipboard data slots. |  247   // where we save it in one of the clipboard data slots. | 
|  248   void CreateNewClipboardData(); |  248   void CreateNewClipboardData(); | 
|  249  |  249  | 
|  250   // Inserts a mapping into clipboard_data_. |  250   // Inserts a mapping into clipboard_data_. | 
|  251   void InsertMapping(const std::string& key, char* data, size_t data_len); |  251   void InsertMapping(const std::string& key, | 
 |  252                      const scoped_refptr<base::RefCountedMemory>& memory); | 
|  252  |  253  | 
|  253   // Moves the temporary |clipboard_data_| to the long term data storage for |  254   // Moves the temporary |clipboard_data_| to the long term data storage for | 
|  254   // |buffer|. |  255   // |buffer|. | 
|  255   void TakeOwnershipOfSelection(Buffer buffer); |  256   void TakeOwnershipOfSelection(Buffer buffer); | 
|  256  |  257  | 
|  257   // Returns the first of |types| offered by the current selection holder in |  258   // Returns the first of |types| offered by the current selection holder in | 
|  258   // |data_out|, or returns NULL if none of those types are available. |  259   // |data_out|, or returns NULL if none of those types are available. | 
|  259   // |  260   // | 
|  260   // If the selection holder is us, this call is synchronous and we pull |  261   // If the selection holder is us, this call is synchronous and we pull | 
|  261   // the data out of |clipboard_selection_| or |primary_selection_|. If the |  262   // the data out of |clipboard_selection_| or |primary_selection_|. If the | 
|  262   // selection holder is some other window, we spin up a nested message loop |  263   // selection holder is some other window, we spin up a nested message loop | 
|  263   // and do the asynchronous dance with whatever application is holding the |  264   // and do the asynchronous dance with whatever application is holding the | 
|  264   // selection. |  265   // selection. | 
|  265   scoped_ptr<SelectionData> RequestAndWaitForTypes( |  266   ui::SelectionData RequestAndWaitForTypes(Buffer buffer, | 
|  266       Buffer buffer, |  267                                            const std::vector< ::Atom>& types); | 
|  267       const std::vector< ::Atom>& types); |  | 
|  268  |  268  | 
|  269   // Retrieves the list of possible data types the current clipboard owner has. |  269   // Retrieves the list of possible data types the current clipboard owner has. | 
|  270   // |  270   // | 
|  271   // If the selection holder is us, this is synchronous, otherwise this runs a |  271   // If the selection holder is us, this is synchronous, otherwise this runs a | 
|  272   // blocking message loop. |  272   // blocking message loop. | 
|  273   TargetList WaitAndGetTargetsList(Buffer buffer); |  273   TargetList WaitAndGetTargetsList(Buffer buffer); | 
|  274  |  274  | 
|  275   // Returns a list of all text atoms that we handle. |  275   // Returns a list of all text atoms that we handle. | 
|  276   std::vector< ::Atom> GetTextAtoms() const; |  276   std::vector< ::Atom> GetTextAtoms() const; | 
|  277  |  277  | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
|  292   // Input-only window used as a selection owner. |  292   // Input-only window used as a selection owner. | 
|  293   ::Window x_window_; |  293   ::Window x_window_; | 
|  294  |  294  | 
|  295   X11AtomCache atom_cache_; |  295   X11AtomCache atom_cache_; | 
|  296  |  296  | 
|  297   // Objects which request and receive selection data. |  297   // Objects which request and receive selection data. | 
|  298   SelectionRequestor clipboard_requestor_; |  298   SelectionRequestor clipboard_requestor_; | 
|  299   SelectionRequestor primary_requestor_; |  299   SelectionRequestor primary_requestor_; | 
|  300  |  300  | 
|  301   // Temporary target map that we write to during DispatchObects. |  301   // Temporary target map that we write to during DispatchObects. | 
|  302   scoped_ptr<SelectionFormatMap> clipboard_data_; |  302   SelectionFormatMap clipboard_data_; | 
|  303  |  303  | 
|  304   // Objects which offer selection data to other windows. |  304   // Objects which offer selection data to other windows. | 
|  305   SelectionOwner clipboard_owner_; |  305   SelectionOwner clipboard_owner_; | 
|  306   SelectionOwner primary_owner_; |  306   SelectionOwner primary_owner_; | 
|  307  |  307  | 
|  308   DISALLOW_COPY_AND_ASSIGN(AuraX11Details); |  308   DISALLOW_COPY_AND_ASSIGN(AuraX11Details); | 
|  309 }; |  309 }; | 
|  310  |  310  | 
|  311 Clipboard::AuraX11Details::AuraX11Details() |  311 Clipboard::AuraX11Details::AuraX11Details() | 
|  312     : x_display_(GetXDisplay()), |  312     : x_display_(GetXDisplay()), | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  338 Clipboard::AuraX11Details::~AuraX11Details() { |  338 Clipboard::AuraX11Details::~AuraX11Details() { | 
|  339   base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); |  339   base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); | 
|  340  |  340  | 
|  341   XDestroyWindow(x_display_, x_window_); |  341   XDestroyWindow(x_display_, x_window_); | 
|  342 } |  342 } | 
|  343  |  343  | 
|  344 ::Atom Clipboard::AuraX11Details::LookupSelectionForBuffer( |  344 ::Atom Clipboard::AuraX11Details::LookupSelectionForBuffer( | 
|  345     Buffer buffer) const { |  345     Buffer buffer) const { | 
|  346   if (buffer == BUFFER_STANDARD) |  346   if (buffer == BUFFER_STANDARD) | 
|  347     return atom_cache_.GetAtom(kClipboard); |  347     return atom_cache_.GetAtom(kClipboard); | 
|  348   else |  348  | 
|  349     return XA_PRIMARY; |  349   return XA_PRIMARY; | 
|  350 } |  350 } | 
|  351  |  351  | 
|  352 SelectionFormatMap* Clipboard::AuraX11Details::LookupStorageForAtom( |  352 const SelectionFormatMap& Clipboard::AuraX11Details::LookupStorageForAtom( | 
|  353     ::Atom atom) { |  353     ::Atom atom) { | 
|  354   if (atom == XA_PRIMARY) |  354   if (atom == XA_PRIMARY) | 
|  355     return primary_owner_.selection_format_map(); |  355     return primary_owner_.selection_format_map(); | 
|  356   else if (atom == atom_cache_.GetAtom(kClipboard)) |  356  | 
|  357     return clipboard_owner_.selection_format_map(); |  357   DCHECK_EQ(atom_cache_.GetAtom(kClipboard), atom); | 
|  358   else |  358   return clipboard_owner_.selection_format_map(); | 
|  359     return NULL; |  | 
|  360 } |  359 } | 
|  361  |  360  | 
|  362 ui::SelectionRequestor* |  361 ui::SelectionRequestor* | 
|  363 Clipboard::AuraX11Details::GetSelectionRequestorForBuffer(Buffer buffer) { |  362 Clipboard::AuraX11Details::GetSelectionRequestorForBuffer(Buffer buffer) { | 
|  364   if (buffer == BUFFER_STANDARD) |  363   if (buffer == BUFFER_STANDARD) | 
|  365     return &clipboard_requestor_; |  364     return &clipboard_requestor_; | 
|  366   else |  365   else | 
|  367     return &primary_requestor_; |  366     return &primary_requestor_; | 
|  368 } |  367 } | 
|  369  |  368  | 
|  370 void Clipboard::AuraX11Details::CreateNewClipboardData() { |  369 void Clipboard::AuraX11Details::CreateNewClipboardData() { | 
|  371   clipboard_data_.reset(new SelectionFormatMap); |  370   clipboard_data_ = SelectionFormatMap(); | 
|  372 } |  371 } | 
|  373  |  372  | 
|  374 void Clipboard::AuraX11Details::InsertMapping(const std::string& key, |  373 void Clipboard::AuraX11Details::InsertMapping( | 
|  375                                               char* data, |  374     const std::string& key, | 
|  376                                               size_t data_len) { |  375     const scoped_refptr<base::RefCountedMemory>& memory) { | 
|  377   ::Atom atom_key = atom_cache_.GetAtom(key.c_str()); |  376   ::Atom atom_key = atom_cache_.GetAtom(key.c_str()); | 
|  378   clipboard_data_->Insert(atom_key, data, data_len); |  377   clipboard_data_.Insert(atom_key, memory); | 
|  379 } |  378 } | 
|  380  |  379  | 
|  381 void Clipboard::AuraX11Details::TakeOwnershipOfSelection(Buffer buffer) { |  380 void Clipboard::AuraX11Details::TakeOwnershipOfSelection(Buffer buffer) { | 
|  382   if (buffer == BUFFER_STANDARD) |  381   if (buffer == BUFFER_STANDARD) | 
|  383     return clipboard_owner_.TakeOwnershipOfSelection(clipboard_data_.Pass()); |  382     return clipboard_owner_.TakeOwnershipOfSelection(clipboard_data_); | 
|  384   else |  383   else | 
|  385     return primary_owner_.TakeOwnershipOfSelection(clipboard_data_.Pass()); |  384     return primary_owner_.TakeOwnershipOfSelection(clipboard_data_); | 
|  386 } |  385 } | 
|  387  |  386  | 
|  388 scoped_ptr<SelectionData> Clipboard::AuraX11Details::RequestAndWaitForTypes( |  387 SelectionData Clipboard::AuraX11Details::RequestAndWaitForTypes( | 
|  389     Buffer buffer, |  388     Buffer buffer, | 
|  390     const std::vector< ::Atom>& types) { |  389     const std::vector< ::Atom>& types) { | 
|  391   ::Atom selection_name = LookupSelectionForBuffer(buffer); |  390   ::Atom selection_name = LookupSelectionForBuffer(buffer); | 
|  392   if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { |  391   if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { | 
|  393     // We can local fastpath instead of playing the nested message loop game |  392     // We can local fastpath instead of playing the nested message loop game | 
|  394     // with the X server. |  393     // with the X server. | 
|  395     SelectionFormatMap* format_map = LookupStorageForAtom(selection_name); |  394     const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); | 
|  396     DCHECK(format_map); |  | 
|  397  |  395  | 
|  398     for (std::vector< ::Atom>::const_iterator it = types.begin(); |  396     for (std::vector< ::Atom>::const_iterator it = types.begin(); | 
|  399          it != types.end(); ++it) { |  397          it != types.end(); ++it) { | 
|  400       SelectionFormatMap::const_iterator format_map_it = format_map->find(*it); |  398       SelectionFormatMap::const_iterator format_map_it = format_map.find(*it); | 
|  401       if (format_map_it != format_map->end()) { |  399       if (format_map_it != format_map.end()) | 
|  402         scoped_ptr<SelectionData> data_out(new SelectionData); |  400         return SelectionData(format_map_it->first, format_map_it->second); | 
|  403         data_out->Set(format_map_it->first, format_map_it->second.first, |  | 
|  404                       format_map_it->second.second, false); |  | 
|  405         return data_out.Pass(); |  | 
|  406       } |  | 
|  407     } |  401     } | 
|  408   } else { |  402   } else { | 
|  409     TargetList targets = WaitAndGetTargetsList(buffer); |  403     TargetList targets = WaitAndGetTargetsList(buffer); | 
|  410     SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); |  404     SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); | 
|  411  |  405  | 
|  412     std::vector< ::Atom> intersection; |  406     std::vector< ::Atom> intersection; | 
|  413     ui::GetAtomIntersection(targets.target_list(), types, &intersection); |  407     ui::GetAtomIntersection(targets.target_list(), types, &intersection); | 
|  414     return receiver->RequestAndWaitForTypes(intersection); |  408     return receiver->RequestAndWaitForTypes(intersection); | 
|  415   } |  409   } | 
|  416  |  410  | 
|  417   return scoped_ptr<SelectionData>(); |  411   return SelectionData(); | 
|  418 } |  412 } | 
|  419  |  413  | 
|  420 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList( |  414 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList( | 
|  421     Buffer buffer) { |  415     Buffer buffer) { | 
|  422   ::Atom selection_name = LookupSelectionForBuffer(buffer); |  416   ::Atom selection_name = LookupSelectionForBuffer(buffer); | 
|  423   std::vector< ::Atom> out; |  417   std::vector< ::Atom> out; | 
|  424   if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { |  418   if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { | 
|  425     // We can local fastpath and return the list of local targets. |  419     // We can local fastpath and return the list of local targets. | 
|  426     SelectionFormatMap* format_map = LookupStorageForAtom(selection_name); |  420     const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); | 
|  427     DCHECK(format_map); |  | 
|  428  |  421  | 
|  429     for (SelectionFormatMap::const_iterator it = format_map->begin(); |  422     for (SelectionFormatMap::const_iterator it = format_map.begin(); | 
|  430          it != format_map->end(); ++it) { |  423          it != format_map.end(); ++it) { | 
|  431       out.push_back(it->first); |  424       out.push_back(it->first); | 
|  432     } |  425     } | 
|  433   } else { |  426   } else { | 
|  434     unsigned char* data = NULL; |  427     scoped_refptr<base::RefCountedMemory> data; | 
|  435     size_t out_data_items = 0; |  428     size_t out_data_items = 0; | 
|  436     ::Atom out_type = None; |  429     ::Atom out_type = None; | 
|  437  |  430  | 
|  438     SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); |  431     SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); | 
|  439     if (receiver->PerformBlockingConvertSelection(atom_cache_.GetAtom(kTargets), |  432     if (receiver->PerformBlockingConvertSelection(atom_cache_.GetAtom(kTargets), | 
|  440                                                   &data, |  433                                                   &data, | 
|  441                                                   NULL, |  434                                                   NULL, | 
|  442                                                   &out_data_items, |  435                                                   &out_data_items, | 
|  443                                                   &out_type)) { |  436                                                   &out_type)) { | 
|  444       ::Atom* atom_array = reinterpret_cast< ::Atom*>(data); |  437       const ::Atom* atom_array = reinterpret_cast<const ::Atom*>(data->front()); | 
|  445       for (size_t i = 0; i < out_data_items; ++i) |  438       for (size_t i = 0; i < out_data_items; ++i) | 
|  446         out.push_back(atom_array[i]); |  439         out.push_back(atom_array[i]); | 
|  447  |  | 
|  448       XFree(data); |  | 
|  449     } else { |  440     } else { | 
|  450       // There was no target list. Most Java apps doesn't offer a TARGETS list, |  441       // There was no target list. Most Java apps doesn't offer a TARGETS list, | 
|  451       // even though they AWT to. They will offer individual text types if you |  442       // even though they AWT to. They will offer individual text types if you | 
|  452       // ask. If this is the case we attempt to make sense of the contents as |  443       // ask. If this is the case we attempt to make sense of the contents as | 
|  453       // text. This is pretty unfortunate since it means we have to actually |  444       // text. This is pretty unfortunate since it means we have to actually | 
|  454       // copy the data to see if it is available, but at least this path |  445       // copy the data to see if it is available, but at least this path | 
|  455       // shouldn't be hit for conforming programs. |  446       // shouldn't be hit for conforming programs. | 
|  456       std::vector< ::Atom> types = GetTextAtoms(); |  447       std::vector< ::Atom> types = GetTextAtoms(); | 
|  457       for (std::vector< ::Atom>::const_iterator it = types.begin(); |  448       for (std::vector< ::Atom>::const_iterator it = types.begin(); | 
|  458            it != types.end(); ++it) { |  449            it != types.end(); ++it) { | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  592   if (target_list.ContainsText()) |  583   if (target_list.ContainsText()) | 
|  593     types->push_back(UTF8ToUTF16(kMimeTypeText)); |  584     types->push_back(UTF8ToUTF16(kMimeTypeText)); | 
|  594   if (target_list.ContainsFormat(GetHtmlFormatType())) |  585   if (target_list.ContainsFormat(GetHtmlFormatType())) | 
|  595     types->push_back(UTF8ToUTF16(kMimeTypeHTML)); |  586     types->push_back(UTF8ToUTF16(kMimeTypeHTML)); | 
|  596   if (target_list.ContainsFormat(GetRtfFormatType())) |  587   if (target_list.ContainsFormat(GetRtfFormatType())) | 
|  597     types->push_back(UTF8ToUTF16(kMimeTypeRTF)); |  588     types->push_back(UTF8ToUTF16(kMimeTypeRTF)); | 
|  598   if (target_list.ContainsFormat(GetBitmapFormatType())) |  589   if (target_list.ContainsFormat(GetBitmapFormatType())) | 
|  599     types->push_back(UTF8ToUTF16(kMimeTypePNG)); |  590     types->push_back(UTF8ToUTF16(kMimeTypePNG)); | 
|  600   *contains_filenames = false; |  591   *contains_filenames = false; | 
|  601  |  592  | 
|  602   scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( |  593   SelectionData data(aurax11_details_->RequestAndWaitForTypes( | 
|  603       buffer, |  594       buffer, | 
|  604       aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); |  595       aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); | 
|  605   if (!data.get()) |  596   if (data.IsValid()) | 
|  606     return; |  597     ReadCustomDataTypes(data.GetData(), data.GetSize(), types); | 
|  607  |  | 
|  608   ReadCustomDataTypes(data->data(), data->size(), types); |  | 
|  609 } |  598 } | 
|  610  |  599  | 
|  611 void Clipboard::ReadText(Buffer buffer, string16* result) const { |  600 void Clipboard::ReadText(Buffer buffer, string16* result) const { | 
|  612   DCHECK(CalledOnValidThread()); |  601   DCHECK(CalledOnValidThread()); | 
|  613  |  602  | 
|  614   scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( |  603   SelectionData data(aurax11_details_->RequestAndWaitForTypes( | 
|  615       buffer, aurax11_details_->GetTextAtoms())); |  604       buffer, aurax11_details_->GetTextAtoms())); | 
|  616   if (data.get()) { |  605   if (data.IsValid()) { | 
|  617     std::string text = data->GetText(); |  606     std::string text = data.GetText(); | 
|  618     *result = UTF8ToUTF16(text); |  607     *result = UTF8ToUTF16(text); | 
|  619   } |  608   } | 
|  620 } |  609 } | 
|  621  |  610  | 
|  622 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const { |  611 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const { | 
|  623   DCHECK(CalledOnValidThread()); |  612   DCHECK(CalledOnValidThread()); | 
|  624  |  613  | 
|  625   scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( |  614   SelectionData data(aurax11_details_->RequestAndWaitForTypes( | 
|  626       buffer, aurax11_details_->GetTextAtoms())); |  615       buffer, aurax11_details_->GetTextAtoms())); | 
|  627   if (data.get()) |  616   if (data.IsValid()) | 
|  628     result->assign(data->GetText()); |  617     result->assign(data.GetText()); | 
|  629 } |  618 } | 
|  630  |  619  | 
|  631 // TODO(estade): handle different charsets. |  620 // TODO(estade): handle different charsets. | 
|  632 // TODO(port): set *src_url. |  621 // TODO(port): set *src_url. | 
|  633 void Clipboard::ReadHTML(Buffer buffer, |  622 void Clipboard::ReadHTML(Buffer buffer, | 
|  634                          string16* markup, |  623                          string16* markup, | 
|  635                          std::string* src_url, |  624                          std::string* src_url, | 
|  636                          uint32* fragment_start, |  625                          uint32* fragment_start, | 
|  637                          uint32* fragment_end) const { |  626                          uint32* fragment_end) const { | 
|  638   DCHECK(CalledOnValidThread()); |  627   DCHECK(CalledOnValidThread()); | 
|  639   markup->clear(); |  628   markup->clear(); | 
|  640   if (src_url) |  629   if (src_url) | 
|  641     src_url->clear(); |  630     src_url->clear(); | 
|  642   *fragment_start = 0; |  631   *fragment_start = 0; | 
|  643   *fragment_end = 0; |  632   *fragment_end = 0; | 
|  644  |  633  | 
|  645   scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( |  634   SelectionData data(aurax11_details_->RequestAndWaitForTypes( | 
|  646       buffer, aurax11_details_->GetAtomsForFormat(GetHtmlFormatType()))); |  635       buffer, aurax11_details_->GetAtomsForFormat(GetHtmlFormatType()))); | 
|  647   if (!data.get()) |  636   if (data.IsValid()) { | 
|  648     return; |  637     *markup = data.GetHtml(); | 
|  649  |  638  | 
|  650   *markup = data->GetHtml(); |  639     *fragment_start = 0; | 
|  651  |  640     DCHECK(markup->length() <= kuint32max); | 
|  652   *fragment_start = 0; |  641     *fragment_end = static_cast<uint32>(markup->length()); | 
|  653   DCHECK(markup->length() <= kuint32max); |  642   } | 
|  654   *fragment_end = static_cast<uint32>(markup->length()); |  | 
|  655 } |  643 } | 
|  656  |  644  | 
|  657 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { |  645 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { | 
|  658   DCHECK(CalledOnValidThread()); |  646   DCHECK(CalledOnValidThread()); | 
|  659  |  647  | 
|  660   scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( |  648   SelectionData data(aurax11_details_->RequestAndWaitForTypes( | 
|  661       buffer, aurax11_details_->GetAtomsForFormat(GetRtfFormatType()))); |  649       buffer, aurax11_details_->GetAtomsForFormat(GetRtfFormatType()))); | 
|  662   if (data.get()) |  650   if (data.IsValid()) | 
|  663     data->AssignTo(result); |  651     data.AssignTo(result); | 
|  664 } |  652 } | 
|  665  |  653  | 
|  666 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |  654 SkBitmap Clipboard::ReadImage(Buffer buffer) const { | 
|  667   DCHECK(CalledOnValidThread()); |  655   DCHECK(CalledOnValidThread()); | 
|  668   NOTIMPLEMENTED(); |  656   NOTIMPLEMENTED(); | 
|  669   return SkBitmap(); |  657   return SkBitmap(); | 
|  670 } |  658 } | 
|  671  |  659  | 
|  672 void Clipboard::ReadCustomData(Buffer buffer, |  660 void Clipboard::ReadCustomData(Buffer buffer, | 
|  673                                const string16& type, |  661                                const string16& type, | 
|  674                                string16* result) const { |  662                                string16* result) const { | 
|  675   DCHECK(CalledOnValidThread()); |  663   DCHECK(CalledOnValidThread()); | 
|  676  |  664  | 
|  677   scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( |  665   SelectionData data(aurax11_details_->RequestAndWaitForTypes( | 
|  678       buffer, |  666       buffer, | 
|  679       aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); |  667       aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); | 
|  680   if (!data.get()) |  668   if (data.IsValid()) | 
|  681     return; |  669     ReadCustomDataForType(data.GetData(), data.GetSize(), type, result); | 
|  682  |  | 
|  683   ReadCustomDataForType(data->data(), data->size(), type, result); |  | 
|  684 } |  670 } | 
|  685  |  671  | 
|  686 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |  672 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 
|  687   DCHECK(CalledOnValidThread()); |  673   DCHECK(CalledOnValidThread()); | 
|  688   // TODO(erg): This was left NOTIMPLEMENTED() in the gtk port too. |  674   // TODO(erg): This was left NOTIMPLEMENTED() in the gtk port too. | 
|  689   NOTIMPLEMENTED(); |  675   NOTIMPLEMENTED(); | 
|  690 } |  676 } | 
|  691  |  677  | 
|  692 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |  678 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 
|  693   DCHECK(CalledOnValidThread()); |  679   DCHECK(CalledOnValidThread()); | 
|  694  |  680  | 
|  695   scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( |  681   SelectionData data(aurax11_details_->RequestAndWaitForTypes( | 
|  696       BUFFER_STANDARD, aurax11_details_->GetAtomsForFormat(format))); |  682       BUFFER_STANDARD, aurax11_details_->GetAtomsForFormat(format))); | 
|  697   if (data.get()) |  683   if (data.IsValid()) | 
|  698     data->AssignTo(result); |  684     data.AssignTo(result); | 
|  699 } |  685 } | 
|  700  |  686  | 
|  701 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |  687 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 
|  702   DCHECK(CalledOnValidThread()); |  688   DCHECK(CalledOnValidThread()); | 
|  703   if (buffer == BUFFER_STANDARD) |  689   if (buffer == BUFFER_STANDARD) | 
|  704     return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); |  690     return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); | 
|  705   else |  691   else | 
|  706     return SelectionChangeObserver::GetInstance()->primary_sequence_number(); |  692     return SelectionChangeObserver::GetInstance()->primary_sequence_number(); | 
|  707 } |  693 } | 
|  708  |  694  | 
|  709 void Clipboard::WriteText(const char* text_data, size_t text_len) { |  695 void Clipboard::WriteText(const char* text_data, size_t text_len) { | 
|  710   char* data = new char[text_len]; |  696   std::string str(text_data, text_len); | 
|  711   memcpy(data, text_data, text_len); |  697   scoped_refptr<base::RefCountedMemory> mem( | 
 |  698       base::RefCountedString::TakeString(&str)); | 
|  712  |  699  | 
|  713   aurax11_details_->InsertMapping(kMimeTypeText, data, text_len); |  700   aurax11_details_->InsertMapping(kMimeTypeText, mem); | 
|  714   aurax11_details_->InsertMapping(kText, data, text_len); |  701   aurax11_details_->InsertMapping(kText, mem); | 
|  715   aurax11_details_->InsertMapping(kString, data, text_len); |  702   aurax11_details_->InsertMapping(kString, mem); | 
|  716   aurax11_details_->InsertMapping(kUtf8String, data, text_len); |  703   aurax11_details_->InsertMapping(kUtf8String, mem); | 
|  717 } |  704 } | 
|  718  |  705  | 
|  719 void Clipboard::WriteHTML(const char* markup_data, |  706 void Clipboard::WriteHTML(const char* markup_data, | 
|  720                           size_t markup_len, |  707                           size_t markup_len, | 
|  721                           const char* url_data, |  708                           const char* url_data, | 
|  722                           size_t url_len) { |  709                           size_t url_len) { | 
|  723   // TODO(estade): We need to expand relative links with |url_data|. |  710   // TODO(estade): We need to expand relative links with |url_data|. | 
|  724   static const char* html_prefix = "<meta http-equiv=\"content-type\" " |  711   static const char* html_prefix = "<meta http-equiv=\"content-type\" " | 
|  725                                    "content=\"text/html; charset=utf-8\">"; |  712                                    "content=\"text/html; charset=utf-8\">"; | 
|  726   size_t html_prefix_len = strlen(html_prefix); |  713   std::string data = html_prefix; | 
|  727   size_t total_len = html_prefix_len + markup_len + 1; |  714   data += std::string(markup_data, markup_len); | 
 |  715   // Some programs expect NULL-terminated data. See http://crbug.com/42624 | 
 |  716   data += '\0'; | 
|  728  |  717  | 
|  729   char* data = new char[total_len]; |  718   scoped_refptr<base::RefCountedMemory> mem( | 
|  730   snprintf(data, total_len, "%s", html_prefix); |  719       base::RefCountedString::TakeString(&data)); | 
|  731   memcpy(data + html_prefix_len, markup_data, markup_len); |  720   aurax11_details_->InsertMapping(kMimeTypeHTML, mem); | 
|  732   // Some programs expect NULL-terminated data. See http://crbug.com/42624 |  | 
|  733   data[total_len - 1] = '\0'; |  | 
|  734  |  | 
|  735   aurax11_details_->InsertMapping(kMimeTypeHTML, data, total_len); |  | 
|  736 } |  721 } | 
|  737  |  722  | 
|  738 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { |  723 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { | 
|  739   WriteData(GetRtfFormatType(), rtf_data, data_len); |  724   WriteData(GetRtfFormatType(), rtf_data, data_len); | 
|  740 } |  725 } | 
|  741  |  726  | 
|  742 void Clipboard::WriteBookmark(const char* title_data, |  727 void Clipboard::WriteBookmark(const char* title_data, | 
|  743                               size_t title_len, |  728                               size_t title_len, | 
|  744                               const char* url_data, |  729                               const char* url_data, | 
|  745                               size_t url_len) { |  730                               size_t url_len) { | 
|  746   // Write as a mozilla url (UTF16: URL, newline, title). |  731   // Write as a mozilla url (UTF16: URL, newline, title). | 
|  747   string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); |  732   string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); | 
|  748   string16 title = UTF8ToUTF16(std::string(title_data, title_len)); |  733   string16 title = UTF8ToUTF16(std::string(title_data, title_len)); | 
|  749   int data_len = 2 * (title.length() + url.length()); |  | 
|  750  |  734  | 
|  751   char* data = new char[data_len]; |  735   std::vector<unsigned char> data; | 
|  752   memcpy(data, url.data(), 2 * url.length()); |  736   ui::AddString16ToVector(url, &data); | 
|  753   memcpy(data + 2 * url.length(), title.data(), 2 * title.length()); |  737   ui::AddString16ToVector(title, &data); | 
|  754   aurax11_details_->InsertMapping(kMimeTypeMozillaURL, data, data_len); |  738   scoped_refptr<base::RefCountedMemory> mem( | 
 |  739       base::RefCountedBytes::TakeVector(&data)); | 
 |  740  | 
 |  741   aurax11_details_->InsertMapping(kMimeTypeMozillaURL, mem); | 
|  755 } |  742 } | 
|  756  |  743  | 
|  757 // Write an extra flavor that signifies WebKit was the last to modify the |  744 // Write an extra flavor that signifies WebKit was the last to modify the | 
|  758 // pasteboard. This flavor has no data. |  745 // pasteboard. This flavor has no data. | 
|  759 void Clipboard::WriteWebSmartPaste() { |  746 void Clipboard::WriteWebSmartPaste() { | 
|  760   aurax11_details_->InsertMapping(kMimeTypeWebkitSmartPaste, NULL, 0); |  747   aurax11_details_->InsertMapping(kMimeTypeWebkitSmartPaste, | 
 |  748                                   scoped_refptr<base::RefCountedMemory>()); | 
|  761 } |  749 } | 
|  762  |  750  | 
|  763 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { |  751 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { | 
|  764   // TODO(erg): I'm not sure if we should be writting BMP data here or |  752   // TODO(erg): I'm not sure if we should be writting BMP data here or | 
|  765   // not. It's what the GTK port does, but I'm not sure it's the right thing to |  753   // not. It's what the GTK port does, but I'm not sure it's the right thing to | 
|  766   // do. |  754   // do. | 
|  767   NOTIMPLEMENTED(); |  755   NOTIMPLEMENTED(); | 
|  768 } |  756 } | 
|  769  |  757  | 
|  770 void Clipboard::WriteData(const FormatType& format, |  758 void Clipboard::WriteData(const FormatType& format, | 
|  771                           const char* data_data, |  759                           const char* data_data, | 
|  772                           size_t data_len) { |  760                           size_t data_len) { | 
|  773   // We assume that certain mapping types are only written by trusted code. |  761   // We assume that certain mapping types are only written by trusted code. | 
|  774   // Therefore we must upkeep their integrity. |  762   // Therefore we must upkeep their integrity. | 
|  775   if (format.Equals(GetBitmapFormatType())) |  763   if (format.Equals(GetBitmapFormatType())) | 
|  776     return; |  764     return; | 
|  777   char* data = new char[data_len]; |  765  | 
|  778   memcpy(data, data_data, data_len); |  766   std::vector<unsigned char> bytes(data_data, data_data + data_len); | 
|  779   aurax11_details_->InsertMapping(format.ToString(), data, data_len); |  767   scoped_refptr<base::RefCountedMemory> mem( | 
 |  768       base::RefCountedBytes::TakeVector(&bytes)); | 
 |  769   aurax11_details_->InsertMapping(format.ToString(), mem); | 
|  780 } |  770 } | 
|  781  |  771  | 
|  782 // static |  772 // static | 
|  783 Clipboard::FormatType Clipboard::GetFormatType( |  773 Clipboard::FormatType Clipboard::GetFormatType( | 
|  784     const std::string& format_string) { |  774     const std::string& format_string) { | 
|  785   return FormatType::Deserialize(format_string); |  775   return FormatType::Deserialize(format_string); | 
|  786 } |  776 } | 
|  787  |  777  | 
|  788 // static |  778 // static | 
|  789 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { |  779 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  848   return type; |  838   return type; | 
|  849 } |  839 } | 
|  850  |  840  | 
|  851 // static |  841 // static | 
|  852 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { |  842 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { | 
|  853   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); |  843   CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); | 
|  854   return type; |  844   return type; | 
|  855 } |  845 } | 
|  856  |  846  | 
|  857 }  // namespace ui |  847 }  // namespace ui | 
| OLD | NEW |