OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // Many of these functions are based on those found in | 5 // Many of these functions are based on those found in |
6 // webkit/port/platform/PasteboardWin.cpp | 6 // webkit/port/platform/PasteboardWin.cpp |
7 | 7 |
8 #include "ui/base/clipboard/clipboard.h" | 8 #include "ui/base/clipboard/clipboard.h" |
9 | 9 |
10 #include <shlobj.h> | 10 #include <shlobj.h> |
11 #include <shellapi.h> | 11 #include <shellapi.h> |
12 | 12 |
| 13 #include "base/basictypes.h" |
13 #include "base/file_path.h" | 14 #include "base/file_path.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
16 #include "base/shared_memory.h" | 17 #include "base/shared_memory.h" |
17 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 19 #include "base/string_number_conversions.h" |
18 #include "base/string_util.h" | 20 #include "base/string_util.h" |
19 #include "base/string_number_conversions.h" | |
20 #include "base/utf_offset_string_conversions.h" | 21 #include "base/utf_offset_string_conversions.h" |
21 #include "base/utf_string_conversions.h" | 22 #include "base/utf_string_conversions.h" |
22 #include "base/win/scoped_gdi_object.h" | 23 #include "base/win/scoped_gdi_object.h" |
23 #include "base/win/scoped_hdc.h" | 24 #include "base/win/scoped_hdc.h" |
24 #include "base/win/wrapped_window_proc.h" | 25 #include "base/win/wrapped_window_proc.h" |
25 #include "third_party/skia/include/core/SkBitmap.h" | 26 #include "third_party/skia/include/core/SkBitmap.h" |
26 #include "ui/base/clipboard/clipboard_util_win.h" | 27 #include "ui/base/clipboard/clipboard_util_win.h" |
27 #include "ui/base/clipboard/custom_data_helper.h" | 28 #include "ui/base/clipboard/custom_data_helper.h" |
28 #include "ui/gfx/canvas_skia.h" | 29 #include "ui/gfx/canvas_skia.h" |
29 #include "ui/gfx/size.h" | 30 #include "ui/gfx/size.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 void MakeBitmapOpaque(const SkBitmap& bitmap) { | 153 void MakeBitmapOpaque(const SkBitmap& bitmap) { |
153 for (int x = 0; x < bitmap.width(); ++x) { | 154 for (int x = 0; x < bitmap.width(); ++x) { |
154 for (int y = 0; y < bitmap.height(); ++y) { | 155 for (int y = 0; y < bitmap.height(); ++y) { |
155 *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF); | 156 *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF); |
156 } | 157 } |
157 } | 158 } |
158 } | 159 } |
159 | 160 |
160 } // namespace | 161 } // namespace |
161 | 162 |
| 163 Clipboard::FormatType::FormatType() { |
| 164 } |
| 165 |
| 166 Clipboard::FormatType::FormatType(UINT native_format) : data_(native_format) { |
| 167 } |
| 168 |
| 169 Clipboard::FormatType::~FormatType() { |
| 170 } |
| 171 |
| 172 std::string Clipboard::FormatType::Serialize() const { |
| 173 return base::IntToString(data_); |
| 174 } |
| 175 |
| 176 // static |
| 177 Clipboard::FormatType Clipboard::FormatType::Deserialize( |
| 178 const std::string& serialization) { |
| 179 int clipboard_format = -1; |
| 180 if (!base::StringToInt(serialization, &clipboard_format)) { |
| 181 NOTREACHED(); |
| 182 return FormatType(); |
| 183 } |
| 184 return FormatType(clipboard_format); |
| 185 } |
| 186 |
162 Clipboard::Clipboard() : create_window_(false) { | 187 Clipboard::Clipboard() : create_window_(false) { |
163 if (MessageLoop::current()->type() == MessageLoop::TYPE_UI) { | 188 if (MessageLoop::current()->type() == MessageLoop::TYPE_UI) { |
164 // Make a dummy HWND to be the clipboard's owner. | 189 // Make a dummy HWND to be the clipboard's owner. |
165 WNDCLASSEX wcex = {0}; | 190 WNDCLASSEX wcex = {0}; |
166 wcex.cbSize = sizeof(WNDCLASSEX); | 191 wcex.cbSize = sizeof(WNDCLASSEX); |
167 wcex.lpfnWndProc = base::win::WrappedWindowProc<ClipboardOwnerWndProc>; | 192 wcex.lpfnWndProc = base::win::WrappedWindowProc<ClipboardOwnerWndProc>; |
168 wcex.hInstance = GetModuleHandle(NULL); | 193 wcex.hInstance = GetModuleHandle(NULL); |
169 wcex.lpszClassName = L"ClipboardOwnerWindowClass"; | 194 wcex.lpszClassName = L"ClipboardOwnerWindowClass"; |
170 ::RegisterClassEx(&wcex); | 195 ::RegisterClassEx(&wcex); |
171 create_window_ = true; | 196 create_window_ = true; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 ::SelectObject(source_dc, old_source); | 332 ::SelectObject(source_dc, old_source); |
308 ::DeleteObject(old_hbitmap); | 333 ::DeleteObject(old_hbitmap); |
309 ::DeleteObject(old_source); | 334 ::DeleteObject(old_source); |
310 ::DeleteDC(compatible_dc); | 335 ::DeleteDC(compatible_dc); |
311 ::DeleteDC(source_dc); | 336 ::DeleteDC(source_dc); |
312 ::ReleaseDC(NULL, dc); | 337 ::ReleaseDC(NULL, dc); |
313 | 338 |
314 WriteToClipboard(CF_BITMAP, hbitmap); | 339 WriteToClipboard(CF_BITMAP, hbitmap); |
315 } | 340 } |
316 | 341 |
317 void Clipboard::WriteData(const char* format_name, size_t format_len, | 342 void Clipboard::WriteData(const FormatType& format, |
318 const char* data_data, size_t data_len) { | 343 const char* data_data, |
319 std::string format(format_name, format_len); | 344 size_t data_len) { |
320 CLIPFORMAT clip_format = | |
321 ::RegisterClipboardFormat(ASCIIToWide(format).c_str()); | |
322 | |
323 HGLOBAL hdata = ::GlobalAlloc(GMEM_MOVEABLE, data_len); | 345 HGLOBAL hdata = ::GlobalAlloc(GMEM_MOVEABLE, data_len); |
324 if (!hdata) | 346 if (!hdata) |
325 return; | 347 return; |
326 | 348 |
327 char* data = static_cast<char*>(::GlobalLock(hdata)); | 349 char* data = static_cast<char*>(::GlobalLock(hdata)); |
328 memcpy(data, data_data, data_len); | 350 memcpy(data, data_data, data_len); |
329 ::GlobalUnlock(data); | 351 ::GlobalUnlock(data); |
330 WriteToClipboard(clip_format, hdata); | 352 WriteToClipboard(format.ToUINT(), hdata); |
331 } | 353 } |
332 | 354 |
333 void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { | 355 void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { |
334 DCHECK(clipboard_owner_); | 356 DCHECK(clipboard_owner_); |
335 if (handle && !::SetClipboardData(format, handle)) { | 357 if (handle && !::SetClipboardData(format, handle)) { |
336 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); | 358 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); |
337 FreeData(format, handle); | 359 FreeData(format, handle); |
338 } | 360 } |
339 } | 361 } |
340 | 362 |
341 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 363 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
342 DCHECK_EQ(buffer, BUFFER_STANDARD); | 364 DCHECK_EQ(buffer, BUFFER_STANDARD); |
343 return ::GetClipboardSequenceNumber(); | 365 return ::GetClipboardSequenceNumber(); |
344 } | 366 } |
345 | 367 |
346 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, | 368 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, |
347 Clipboard::Buffer buffer) const { | 369 Clipboard::Buffer buffer) const { |
348 DCHECK_EQ(buffer, BUFFER_STANDARD); | 370 DCHECK_EQ(buffer, BUFFER_STANDARD); |
349 int f; | 371 return ::IsClipboardFormatAvailable(format.ToUINT()) != FALSE; |
350 if (!base::StringToInt(format, &f)) | |
351 return false; | |
352 return ::IsClipboardFormatAvailable(f) != FALSE; | |
353 } | |
354 | |
355 bool Clipboard::IsFormatAvailableByString( | |
356 const std::string& ascii_format, Clipboard::Buffer buffer) const { | |
357 DCHECK_EQ(buffer, BUFFER_STANDARD); | |
358 std::wstring wide_format = ASCIIToWide(ascii_format); | |
359 CLIPFORMAT format = ::RegisterClipboardFormat(wide_format.c_str()); | |
360 return ::IsClipboardFormatAvailable(format) != FALSE; | |
361 } | 372 } |
362 | 373 |
363 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, | 374 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, |
364 std::vector<string16>* types, | 375 std::vector<string16>* types, |
365 bool* contains_filenames) const { | 376 bool* contains_filenames) const { |
366 if (!types || !contains_filenames) { | 377 if (!types || !contains_filenames) { |
367 NOTREACHED(); | 378 NOTREACHED(); |
368 return; | 379 return; |
369 } | 380 } |
370 | 381 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 for (int i = 0; i < count; ++i) { | 650 for (int i = 0; i < count; ++i) { |
640 UINT size = ::DragQueryFile(drop, i, NULL, 0) + 1; | 651 UINT size = ::DragQueryFile(drop, i, NULL, 0) + 1; |
641 DCHECK_GT(size, 1u); | 652 DCHECK_GT(size, 1u); |
642 std::wstring file; | 653 std::wstring file; |
643 ::DragQueryFile(drop, i, WriteInto(&file, size), size); | 654 ::DragQueryFile(drop, i, WriteInto(&file, size), size); |
644 files->push_back(FilePath(file)); | 655 files->push_back(FilePath(file)); |
645 } | 656 } |
646 } | 657 } |
647 } | 658 } |
648 | 659 |
649 void Clipboard::ReadData(const std::string& format, std::string* result) const { | 660 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |
650 if (!result) { | 661 if (!result) { |
651 NOTREACHED(); | 662 NOTREACHED(); |
652 return; | 663 return; |
653 } | 664 } |
654 | 665 |
655 CLIPFORMAT clip_format = | |
656 ::RegisterClipboardFormat(ASCIIToWide(format).c_str()); | |
657 | |
658 ScopedClipboard clipboard; | 666 ScopedClipboard clipboard; |
659 if (!clipboard.Acquire(GetClipboardWindow())) | 667 if (!clipboard.Acquire(GetClipboardWindow())) |
660 return; | 668 return; |
661 | 669 |
662 HANDLE data = ::GetClipboardData(clip_format); | 670 HANDLE data = ::GetClipboardData(format.ToUINT()); |
663 if (!data) | 671 if (!data) |
664 return; | 672 return; |
665 | 673 |
666 result->assign(static_cast<const char*>(::GlobalLock(data)), | 674 result->assign(static_cast<const char*>(::GlobalLock(data)), |
667 ::GlobalSize(data)); | 675 ::GlobalSize(data)); |
668 ::GlobalUnlock(data); | 676 ::GlobalUnlock(data); |
669 } | 677 } |
670 | 678 |
671 // static | 679 // static |
672 void Clipboard::ParseBookmarkClipboardFormat(const string16& bookmark, | 680 void Clipboard::ParseBookmarkClipboardFormat(const string16& bookmark, |
673 string16* title, | 681 string16* title, |
674 std::string* url) { | 682 std::string* url) { |
675 const string16 kDelim = ASCIIToUTF16("\r\n"); | 683 const string16 kDelim = ASCIIToUTF16("\r\n"); |
676 | 684 |
677 const size_t title_end = bookmark.find_first_of(kDelim); | 685 const size_t title_end = bookmark.find_first_of(kDelim); |
678 if (title) | 686 if (title) |
679 title->assign(bookmark.substr(0, title_end)); | 687 title->assign(bookmark.substr(0, title_end)); |
680 | 688 |
681 if (url) { | 689 if (url) { |
682 const size_t url_start = bookmark.find_first_not_of(kDelim, title_end); | 690 const size_t url_start = bookmark.find_first_not_of(kDelim, title_end); |
683 if (url_start != string16::npos) | 691 if (url_start != string16::npos) |
684 *url = UTF16ToUTF8(bookmark.substr(url_start, string16::npos)); | 692 *url = UTF16ToUTF8(bookmark.substr(url_start, string16::npos)); |
685 } | 693 } |
686 } | 694 } |
687 | 695 |
688 // static | 696 // static |
689 Clipboard::FormatType Clipboard::GetUrlFormatType() { | 697 Clipboard::FormatType Clipboard::GetFormatType( |
690 return base::IntToString(ClipboardUtil::GetUrlFormat()->cfFormat); | 698 const std::string& format_string) { |
| 699 return FormatType( |
| 700 ::RegisterClipboardFormat(ASCIIToWide(format_string).c_str())); |
691 } | 701 } |
692 | 702 |
693 // static | 703 // static |
694 Clipboard::FormatType Clipboard::GetUrlWFormatType() { | 704 // TODO(dcheng): Just substitue the appropriate constants here. |
695 return base::IntToString(ClipboardUtil::GetUrlWFormat()->cfFormat); | 705 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { |
| 706 CR_DEFINE_STATIC_LOCAL( |
| 707 FormatType, |
| 708 type, |
| 709 (ClipboardUtil::GetUrlFormat()->cfFormat)); |
| 710 return type; |
696 } | 711 } |
697 | 712 |
698 // static | 713 // static |
699 Clipboard::FormatType Clipboard::GetMozUrlFormatType() { | 714 const Clipboard::FormatType& Clipboard::GetUrlWFormatType() { |
700 return base::IntToString(ClipboardUtil::GetMozUrlFormat()->cfFormat); | 715 CR_DEFINE_STATIC_LOCAL( |
| 716 FormatType, |
| 717 type, |
| 718 (ClipboardUtil::GetUrlWFormat()->cfFormat)); |
| 719 return type; |
701 } | 720 } |
702 | 721 |
703 // static | 722 // static |
704 Clipboard::FormatType Clipboard::GetPlainTextFormatType() { | 723 const Clipboard::FormatType& Clipboard::GetMozUrlFormatType() { |
705 return base::IntToString(ClipboardUtil::GetPlainTextFormat()->cfFormat); | 724 CR_DEFINE_STATIC_LOCAL( |
| 725 FormatType, |
| 726 type, |
| 727 (ClipboardUtil::GetMozUrlFormat()->cfFormat)); |
| 728 return type; |
706 } | 729 } |
707 | 730 |
708 // static | 731 // static |
709 Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { | 732 const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() { |
710 return base::IntToString(ClipboardUtil::GetPlainTextWFormat()->cfFormat); | 733 CR_DEFINE_STATIC_LOCAL( |
| 734 FormatType, |
| 735 type, |
| 736 (ClipboardUtil::GetPlainTextFormat()->cfFormat)); |
| 737 return type; |
711 } | 738 } |
712 | 739 |
713 // static | 740 // static |
714 Clipboard::FormatType Clipboard::GetFilenameFormatType() { | 741 const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() { |
715 return base::IntToString(ClipboardUtil::GetFilenameFormat()->cfFormat); | 742 CR_DEFINE_STATIC_LOCAL( |
| 743 FormatType, |
| 744 type, |
| 745 (ClipboardUtil::GetPlainTextWFormat()->cfFormat)); |
| 746 return type; |
716 } | 747 } |
717 | 748 |
718 // static | 749 // static |
719 Clipboard::FormatType Clipboard::GetFilenameWFormatType() { | 750 const Clipboard::FormatType& Clipboard::GetFilenameFormatType() { |
720 return base::IntToString(ClipboardUtil::GetFilenameWFormat()->cfFormat); | 751 CR_DEFINE_STATIC_LOCAL( |
| 752 FormatType, |
| 753 type, |
| 754 (ClipboardUtil::GetFilenameFormat()->cfFormat)); |
| 755 return type; |
| 756 } |
| 757 |
| 758 // static |
| 759 const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() { |
| 760 CR_DEFINE_STATIC_LOCAL( |
| 761 FormatType, |
| 762 type, |
| 763 (ClipboardUtil::GetFilenameWFormat()->cfFormat)); |
| 764 return type; |
721 } | 765 } |
722 | 766 |
723 // MS HTML Format | 767 // MS HTML Format |
724 // static | 768 // static |
725 Clipboard::FormatType Clipboard::GetHtmlFormatType() { | 769 const Clipboard::FormatType& Clipboard::GetHtmlFormatType() { |
726 return base::IntToString(ClipboardUtil::GetHtmlFormat()->cfFormat); | 770 CR_DEFINE_STATIC_LOCAL( |
| 771 FormatType, |
| 772 type, |
| 773 (ClipboardUtil::GetHtmlFormat()->cfFormat)); |
| 774 return type; |
727 } | 775 } |
728 | 776 |
729 // static | 777 // static |
730 Clipboard::FormatType Clipboard::GetBitmapFormatType() { | 778 const Clipboard::FormatType& Clipboard::GetBitmapFormatType() { |
731 return base::IntToString(CF_BITMAP); | 779 CR_DEFINE_STATIC_LOCAL(FormatType, type, (CF_BITMAP)); |
| 780 return type; |
732 } | 781 } |
733 | 782 |
734 // Firefox text/html | 783 // Firefox text/html |
735 // static | 784 // static |
736 Clipboard::FormatType Clipboard::GetTextHtmlFormatType() { | 785 const Clipboard::FormatType& Clipboard::GetTextHtmlFormatType() { |
737 return base::IntToString(ClipboardUtil::GetTextHtmlFormat()->cfFormat); | 786 CR_DEFINE_STATIC_LOCAL( |
| 787 FormatType, |
| 788 type, |
| 789 (ClipboardUtil::GetTextHtmlFormat()->cfFormat)); |
| 790 return type; |
738 } | 791 } |
739 | 792 |
740 // static | 793 // static |
741 Clipboard::FormatType Clipboard::GetCFHDropFormatType() { | 794 const Clipboard::FormatType& Clipboard::GetCFHDropFormatType() { |
742 return base::IntToString(ClipboardUtil::GetCFHDropFormat()->cfFormat); | 795 CR_DEFINE_STATIC_LOCAL( |
| 796 FormatType, |
| 797 type, |
| 798 (ClipboardUtil::GetCFHDropFormat()->cfFormat)); |
| 799 return type; |
743 } | 800 } |
744 | 801 |
745 // static | 802 // static |
746 Clipboard::FormatType Clipboard::GetFileDescriptorFormatType() { | 803 const Clipboard::FormatType& Clipboard::GetFileDescriptorFormatType() { |
747 return base::IntToString(ClipboardUtil::GetFileDescriptorFormat()->cfFormat); | 804 CR_DEFINE_STATIC_LOCAL( |
| 805 FormatType, |
| 806 type, |
| 807 (ClipboardUtil::GetFileDescriptorFormat()->cfFormat)); |
| 808 return type; |
748 } | 809 } |
749 | 810 |
750 // static | 811 // static |
751 Clipboard::FormatType Clipboard::GetFileContentFormatZeroType() { | 812 const Clipboard::FormatType& Clipboard::GetFileContentFormatZeroType() { |
752 return base::IntToString(ClipboardUtil::GetFileContentFormatZero()->cfFormat); | 813 CR_DEFINE_STATIC_LOCAL( |
| 814 FormatType, |
| 815 type, |
| 816 (ClipboardUtil::GetFileContentFormatZero()->cfFormat)); |
| 817 return type; |
753 } | 818 } |
754 | 819 |
755 // static | 820 // static |
756 Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { | 821 const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() { |
757 return base::IntToString( | 822 CR_DEFINE_STATIC_LOCAL( |
758 ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat); | 823 FormatType, |
| 824 type, |
| 825 (ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat)); |
| 826 return type; |
759 } | 827 } |
760 | 828 |
761 // static | 829 // static |
762 Clipboard::FormatType Clipboard::GetWebCustomDataFormatType() { | 830 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { |
763 // TODO(dcheng): Clean up the duplicated constant. | 831 CR_DEFINE_STATIC_LOCAL( |
764 // Clipboard::WritePickledData() takes a FormatType, but all the callers | 832 FormatType, |
765 // assume that it's a raw string. As a result, we return the format name here | 833 type, |
766 // rather than returning a string-ified version of the registered clipboard | 834 (ClipboardUtil::GetWebCustomDataFormat()->cfFormat)); |
767 // format ID. | 835 return type; |
768 return "Chromium Web Custom MIME Data Format"; | |
769 } | 836 } |
770 | 837 |
771 // static | 838 // static |
772 void Clipboard::FreeData(unsigned int format, HANDLE data) { | 839 void Clipboard::FreeData(unsigned int format, HANDLE data) { |
773 if (format == CF_BITMAP) | 840 if (format == CF_BITMAP) |
774 ::DeleteObject(static_cast<HBITMAP>(data)); | 841 ::DeleteObject(static_cast<HBITMAP>(data)); |
775 else | 842 else |
776 ::GlobalFree(data); | 843 ::GlobalFree(data); |
777 } | 844 } |
778 | 845 |
779 HWND Clipboard::GetClipboardWindow() const { | 846 HWND Clipboard::GetClipboardWindow() const { |
780 if (!clipboard_owner_ && create_window_) { | 847 if (!clipboard_owner_ && create_window_) { |
781 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", | 848 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", |
782 L"ClipboardOwnerWindow", | 849 L"ClipboardOwnerWindow", |
783 0, 0, 0, 0, 0, | 850 0, 0, 0, 0, 0, |
784 HWND_MESSAGE, | 851 HWND_MESSAGE, |
785 0, 0, 0); | 852 0, 0, 0); |
786 } | 853 } |
787 return clipboard_owner_; | 854 return clipboard_owner_; |
788 } | 855 } |
789 | 856 |
790 } // namespace ui | 857 } // namespace ui |
OLD | NEW |