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