| 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 <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 #include <X11/extensions/Xfixes.h> | 8 #include <X11/extensions/Xfixes.h> |
| 9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 clipboard_sequence_number_++; | 99 clipboard_sequence_number_++; |
| 100 } else if (ev->selection == XA_PRIMARY) { | 100 } else if (ev->selection == XA_PRIMARY) { |
| 101 primary_sequence_number_++; | 101 primary_sequence_number_++; |
| 102 } else { | 102 } else { |
| 103 DLOG(ERROR) << "Unexpected selection atom: " << ev->selection; | 103 DLOG(ERROR) << "Unexpected selection atom: " << ev->selection; |
| 104 } | 104 } |
| 105 } | 105 } |
| 106 return GDK_FILTER_CONTINUE; | 106 return GDK_FILTER_CONTINUE; |
| 107 } | 107 } |
| 108 | 108 |
| 109 const char kSourceTagType[] = "org.chromium.source-tag"; |
| 109 const char kMimeTypeBitmap[] = "image/bmp"; | 110 const char kMimeTypeBitmap[] = "image/bmp"; |
| 110 const char kMimeTypeMozillaURL[] = "text/x-moz-url"; | 111 const char kMimeTypeMozillaURL[] = "text/x-moz-url"; |
| 111 const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data"; | 112 const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data"; |
| 112 const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; | 113 const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; |
| 113 | 114 |
| 114 std::string GdkAtomToString(const GdkAtom& atom) { | 115 std::string GdkAtomToString(const GdkAtom& atom) { |
| 115 gchar* name = gdk_atom_name(atom); | 116 gchar* name = gdk_atom_name(atom); |
| 116 std::string rv(name); | 117 std::string rv(name); |
| 117 g_free(name); | 118 g_free(name); |
| 118 return rv; | 119 return rv; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 DCHECK(CalledOnValidThread()); | 211 DCHECK(CalledOnValidThread()); |
| 211 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); | 212 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); |
| 212 primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); | 213 primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
| 213 } | 214 } |
| 214 | 215 |
| 215 Clipboard::~Clipboard() { | 216 Clipboard::~Clipboard() { |
| 216 DCHECK(CalledOnValidThread()); | 217 DCHECK(CalledOnValidThread()); |
| 217 gtk_clipboard_store(clipboard_); | 218 gtk_clipboard_store(clipboard_); |
| 218 } | 219 } |
| 219 | 220 |
| 220 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { | 221 void Clipboard::WriteObjectsImpl(Buffer buffer, |
| 222 const ObjectMap& objects, |
| 223 SourceTag tag) { |
| 221 DCHECK(CalledOnValidThread()); | 224 DCHECK(CalledOnValidThread()); |
| 222 clipboard_data_ = new TargetMap(); | 225 clipboard_data_ = new TargetMap(); |
| 223 | 226 |
| 224 for (ObjectMap::const_iterator iter = objects.begin(); | 227 for (ObjectMap::const_iterator iter = objects.begin(); |
| 225 iter != objects.end(); ++iter) { | 228 iter != objects.end(); ++iter) { |
| 226 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | 229 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 227 } | 230 } |
| 231 WriteSourceTag(tag); |
| 228 | 232 |
| 229 SetGtkClipboard(buffer); | 233 SetGtkClipboard(buffer); |
| 230 } | 234 } |
| 231 | 235 |
| 232 // Take ownership of the GTK clipboard and inform it of the targets we support. | 236 // Take ownership of the GTK clipboard and inform it of the targets we support. |
| 233 void Clipboard::SetGtkClipboard(Buffer buffer) { | 237 void Clipboard::SetGtkClipboard(Buffer buffer) { |
| 234 scoped_ptr<GtkTargetEntry[]> targets( | 238 scoped_ptr<GtkTargetEntry[]> targets( |
| 235 new GtkTargetEntry[clipboard_data_->size()]); | 239 new GtkTargetEntry[clipboard_data_->size()]); |
| 236 | 240 |
| 237 int i = 0; | 241 int i = 0; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 // We assume that certain mapping types are only written by trusted code. | 347 // We assume that certain mapping types are only written by trusted code. |
| 344 // Therefore we must upkeep their integrity. | 348 // Therefore we must upkeep their integrity. |
| 345 if (format.Equals(GetBitmapFormatType())) | 349 if (format.Equals(GetBitmapFormatType())) |
| 346 return; | 350 return; |
| 347 char* data = new char[data_len]; | 351 char* data = new char[data_len]; |
| 348 memcpy(data, data_data, data_len); | 352 memcpy(data, data_data, data_len); |
| 349 // TODO(dcheng): Maybe this map should use GdkAtoms... | 353 // TODO(dcheng): Maybe this map should use GdkAtoms... |
| 350 InsertMapping(GdkAtomToString(format.ToGdkAtom()).c_str(), data, data_len); | 354 InsertMapping(GdkAtomToString(format.ToGdkAtom()).c_str(), data, data_len); |
| 351 } | 355 } |
| 352 | 356 |
| 357 void Clipboard::WriteSourceTag(SourceTag tag) { |
| 358 if (tag != SourceTag()) { |
| 359 ObjectMapParam binary = SourceTag2Binary(tag); |
| 360 WriteData(GetSourceTagFormatType(), &binary[0], binary.size()); |
| 361 } |
| 362 } |
| 363 |
| 353 // We do not use gtk_clipboard_wait_is_target_available because of | 364 // We do not use gtk_clipboard_wait_is_target_available because of |
| 354 // a bug with the gtk clipboard. It caches the available targets | 365 // a bug with the gtk clipboard. It caches the available targets |
| 355 // and does not always refresh the cache when it is appropriate. | 366 // and does not always refresh the cache when it is appropriate. |
| 356 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, | 367 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, |
| 357 Clipboard::Buffer buffer) const { | 368 Clipboard::Buffer buffer) const { |
| 358 DCHECK(CalledOnValidThread()); | 369 DCHECK(CalledOnValidThread()); |
| 359 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 370 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 360 if (clipboard == NULL) | 371 if (clipboard == NULL) |
| 361 return false; | 372 return false; |
| 362 | 373 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 GtkSelectionData* data = | 591 GtkSelectionData* data = |
| 581 gtk_clipboard_wait_for_contents(clipboard_, format.ToGdkAtom()); | 592 gtk_clipboard_wait_for_contents(clipboard_, format.ToGdkAtom()); |
| 582 if (!data) | 593 if (!data) |
| 583 return; | 594 return; |
| 584 result->assign(reinterpret_cast<const char*>( | 595 result->assign(reinterpret_cast<const char*>( |
| 585 gtk_selection_data_get_data(data)), | 596 gtk_selection_data_get_data(data)), |
| 586 gtk_selection_data_get_length(data)); | 597 gtk_selection_data_get_length(data)); |
| 587 gtk_selection_data_free(data); | 598 gtk_selection_data_free(data); |
| 588 } | 599 } |
| 589 | 600 |
| 601 Clipboard::SourceTag Clipboard::ReadSourceTag() const { |
| 602 std::string result; |
| 603 ReadData(GetSourceTagFormatType(), &result); |
| 604 return Binary2SourceTag(result); |
| 605 } |
| 606 |
| 590 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 607 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
| 591 DCHECK(CalledOnValidThread()); | 608 DCHECK(CalledOnValidThread()); |
| 592 if (buffer == BUFFER_STANDARD) | 609 if (buffer == BUFFER_STANDARD) |
| 593 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); | 610 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); |
| 594 else | 611 else |
| 595 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); | 612 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); |
| 596 } | 613 } |
| 597 | 614 |
| 598 //static | 615 //static |
| 599 Clipboard::FormatType Clipboard::GetFormatType( | 616 Clipboard::FormatType Clipboard::GetFormatType( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData)); | 669 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData)); |
| 653 return type; | 670 return type; |
| 654 } | 671 } |
| 655 | 672 |
| 656 // static | 673 // static |
| 657 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { | 674 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { |
| 658 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); | 675 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); |
| 659 return type; | 676 return type; |
| 660 } | 677 } |
| 661 | 678 |
| 679 // static |
| 680 const Clipboard::FormatType& Clipboard::GetSourceTagFormatType() { |
| 681 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kSourceTagType)); |
| 682 return type; |
| 683 } |
| 684 |
| 662 void Clipboard::InsertMapping(const char* key, | 685 void Clipboard::InsertMapping(const char* key, |
| 663 char* data, | 686 char* data, |
| 664 size_t data_len) { | 687 size_t data_len) { |
| 665 DCHECK(clipboard_data_->find(key) == clipboard_data_->end()); | 688 DCHECK(clipboard_data_->find(key) == clipboard_data_->end()); |
| 666 (*clipboard_data_)[key] = std::make_pair(data, data_len); | 689 (*clipboard_data_)[key] = std::make_pair(data, data_len); |
| 667 } | 690 } |
| 668 | 691 |
| 669 GtkClipboard* Clipboard::LookupBackingClipboard(Buffer clipboard) const { | 692 GtkClipboard* Clipboard::LookupBackingClipboard(Buffer clipboard) const { |
| 670 switch (clipboard) { | 693 switch (clipboard) { |
| 671 case BUFFER_STANDARD: | 694 case BUFFER_STANDARD: |
| 672 return clipboard_; | 695 return clipboard_; |
| 673 case BUFFER_SELECTION: | 696 case BUFFER_SELECTION: |
| 674 return primary_selection_; | 697 return primary_selection_; |
| 675 default: | 698 default: |
| 676 NOTREACHED(); | 699 NOTREACHED(); |
| 677 return NULL; | 700 return NULL; |
| 678 } | 701 } |
| 679 } | 702 } |
| 680 | 703 |
| 681 } // namespace ui | 704 } // namespace ui |
| OLD | NEW |