Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: ui/base/clipboard/clipboard_win.cc

Issue 8801038: Make Clipboard::FormatType an opaque handle type. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Linux build too? Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698