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

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

Issue 658963003: Change Clipboard to use virtual methods for testing purposes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments Created 6 years, 2 months 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
« no previous file with comments | « ui/base/clipboard/clipboard_win.h ('k') | ui/base/ui_base.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // 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_win.h"
9 9
10 #include <shellapi.h> 10 #include <shellapi.h>
11 #include <shlobj.h> 11 #include <shlobj.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/shared_memory.h" 17 #include "base/memory/shared_memory.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 } 152 }
153 153
154 void MakeBitmapOpaque(const SkBitmap& bitmap) { 154 void MakeBitmapOpaque(const SkBitmap& bitmap) {
155 for (int x = 0; x < bitmap.width(); ++x) { 155 for (int x = 0; x < bitmap.width(); ++x) {
156 for (int y = 0; y < bitmap.height(); ++y) { 156 for (int y = 0; y < bitmap.height(); ++y) {
157 *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF); 157 *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF);
158 } 158 }
159 } 159 }
160 } 160 }
161 161
162 void ParseBookmarkClipboardFormat(const base::string16& bookmark,
163 base::string16* title,
164 std::string* url) {
165 const base::string16 kDelim = base::ASCIIToUTF16("\r\n");
166
167 const size_t title_end = bookmark.find_first_of(kDelim);
168 if (title)
169 title->assign(bookmark.substr(0, title_end));
170
171 if (url) {
172 const size_t url_start = bookmark.find_first_not_of(kDelim, title_end);
173 if (url_start != base::string16::npos) {
174 *url =
175 base::UTF16ToUTF8(bookmark.substr(url_start, base::string16::npos));
176 }
177 }
178 }
179
180 void FreeData(unsigned int format, HANDLE data) {
181 if (format == CF_BITMAP)
182 ::DeleteObject(static_cast<HBITMAP>(data));
183 else
184 ::GlobalFree(data);
185 }
186
162 } // namespace 187 } // namespace
163 188
164 // Clipboard::FormatType implementation. 189 // Clipboard::FormatType implementation.
165 Clipboard::FormatType::FormatType() : data_() {} 190 Clipboard::FormatType::FormatType() : data_() {}
166 191
167 Clipboard::FormatType::FormatType(UINT native_format) : data_() { 192 Clipboard::FormatType::FormatType(UINT native_format) : data_() {
168 // There's no good way to actually initialize this in the constructor in 193 // There's no good way to actually initialize this in the constructor in
169 // C++03. 194 // C++03.
170 data_.cfFormat = native_format; 195 data_.cfFormat = native_format;
171 data_.dwAspect = DVASPECT_CONTENT; 196 data_.dwAspect = DVASPECT_CONTENT;
(...skipping 22 matching lines...) Expand all
194 const std::string& serialization) { 219 const std::string& serialization) {
195 int clipboard_format = -1; 220 int clipboard_format = -1;
196 if (!base::StringToInt(serialization, &clipboard_format)) { 221 if (!base::StringToInt(serialization, &clipboard_format)) {
197 NOTREACHED(); 222 NOTREACHED();
198 return FormatType(); 223 return FormatType();
199 } 224 }
200 return FormatType(clipboard_format); 225 return FormatType(clipboard_format);
201 } 226 }
202 227
203 bool Clipboard::FormatType::operator<(const FormatType& other) const { 228 bool Clipboard::FormatType::operator<(const FormatType& other) const {
204 return ToUINT() < other.ToUINT(); 229 return data_.cfFormat < other.data_.cfFormat;
205 } 230 }
206 231
207 bool Clipboard::FormatType::Equals(const FormatType& other) const { 232 bool Clipboard::FormatType::Equals(const FormatType& other) const {
208 return ToUINT() == other.ToUINT(); 233 return data_.cfFormat == other.data_.cfFormat;
209 } 234 }
210 235
211 // Various predefined FormatTypes. 236 // Various predefined FormatTypes.
212 // static 237 // static
213 Clipboard::FormatType Clipboard::GetFormatType( 238 Clipboard::FormatType Clipboard::GetFormatType(
214 const std::string& format_string) { 239 const std::string& format_string) {
215 return FormatType( 240 return FormatType(
216 ::RegisterClipboardFormat(base::ASCIIToWide(format_string).c_str())); 241 ::RegisterClipboardFormat(base::ASCIIToWide(format_string).c_str()));
217 } 242 }
218 243
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 366
342 // static 367 // static
343 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { 368 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
344 CR_DEFINE_STATIC_LOCAL( 369 CR_DEFINE_STATIC_LOCAL(
345 FormatType, 370 FormatType,
346 type, 371 type,
347 (::RegisterClipboardFormat(L"Chromium Pepper MIME Data Format"))); 372 (::RegisterClipboardFormat(L"Chromium Pepper MIME Data Format")));
348 return type; 373 return type;
349 } 374 }
350 375
351 // Clipboard implementation. 376 // Clipboard factory method.
352 Clipboard::Clipboard() { 377 // static
378 Clipboard* Clipboard::Create() {
379 return new ClipboardWin;
380 }
381
382 // ClipboardWin implementation.
383 ClipboardWin::ClipboardWin() {
353 if (base::MessageLoopForUI::IsCurrent()) 384 if (base::MessageLoopForUI::IsCurrent())
354 clipboard_owner_.reset(new base::win::MessageWindow()); 385 clipboard_owner_.reset(new base::win::MessageWindow());
355 } 386 }
356 387
357 Clipboard::~Clipboard() { 388 ClipboardWin::~ClipboardWin() {
358 } 389 }
359 390
360 uint64 Clipboard::GetSequenceNumber(ClipboardType type) { 391 uint64 ClipboardWin::GetSequenceNumber(ClipboardType type) {
361 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 392 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
362 return ::GetClipboardSequenceNumber(); 393 return ::GetClipboardSequenceNumber();
363 } 394 }
364 395
365 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, 396 bool ClipboardWin::IsFormatAvailable(const Clipboard::FormatType& format,
366 ClipboardType type) const { 397 ClipboardType type) const {
367 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 398 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
368 return ::IsClipboardFormatAvailable(format.ToUINT()) != FALSE; 399 return ::IsClipboardFormatAvailable(format.ToFormatEtc().cfFormat) != FALSE;
369 } 400 }
370 401
371 void Clipboard::Clear(ClipboardType type) { 402 void ClipboardWin::Clear(ClipboardType type) {
372 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 403 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
373 ScopedClipboard clipboard; 404 ScopedClipboard clipboard;
374 if (!clipboard.Acquire(GetClipboardWindow())) 405 if (!clipboard.Acquire(GetClipboardWindow()))
375 return; 406 return;
376 407
377 ::EmptyClipboard(); 408 ::EmptyClipboard();
378 } 409 }
379 410
380 void Clipboard::ReadAvailableTypes(ClipboardType type, 411 void ClipboardWin::ReadAvailableTypes(ClipboardType type,
381 std::vector<base::string16>* types, 412 std::vector<base::string16>* types,
382 bool* contains_filenames) const { 413 bool* contains_filenames) const {
383 if (!types || !contains_filenames) { 414 if (!types || !contains_filenames) {
384 NOTREACHED(); 415 NOTREACHED();
385 return; 416 return;
386 } 417 }
387 418
388 types->clear(); 419 types->clear();
389 if (::IsClipboardFormatAvailable(GetPlainTextFormatType().ToUINT())) 420 if (::IsClipboardFormatAvailable(
421 GetPlainTextFormatType().ToFormatEtc().cfFormat))
390 types->push_back(base::UTF8ToUTF16(kMimeTypeText)); 422 types->push_back(base::UTF8ToUTF16(kMimeTypeText));
391 if (::IsClipboardFormatAvailable(GetHtmlFormatType().ToUINT())) 423 if (::IsClipboardFormatAvailable(GetHtmlFormatType().ToFormatEtc().cfFormat))
392 types->push_back(base::UTF8ToUTF16(kMimeTypeHTML)); 424 types->push_back(base::UTF8ToUTF16(kMimeTypeHTML));
393 if (::IsClipboardFormatAvailable(GetRtfFormatType().ToUINT())) 425 if (::IsClipboardFormatAvailable(GetRtfFormatType().ToFormatEtc().cfFormat))
394 types->push_back(base::UTF8ToUTF16(kMimeTypeRTF)); 426 types->push_back(base::UTF8ToUTF16(kMimeTypeRTF));
395 if (::IsClipboardFormatAvailable(CF_DIB)) 427 if (::IsClipboardFormatAvailable(CF_DIB))
396 types->push_back(base::UTF8ToUTF16(kMimeTypePNG)); 428 types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
397 *contains_filenames = false; 429 *contains_filenames = false;
398 430
399 // Acquire the clipboard. 431 // Acquire the clipboard.
400 ScopedClipboard clipboard; 432 ScopedClipboard clipboard;
401 if (!clipboard.Acquire(GetClipboardWindow())) 433 if (!clipboard.Acquire(GetClipboardWindow()))
402 return; 434 return;
403 435
404 HANDLE hdata = ::GetClipboardData(GetWebCustomDataFormatType().ToUINT()); 436 HANDLE hdata =
437 ::GetClipboardData(GetWebCustomDataFormatType().ToFormatEtc().cfFormat);
405 if (!hdata) 438 if (!hdata)
406 return; 439 return;
407 440
408 ReadCustomDataTypes(::GlobalLock(hdata), ::GlobalSize(hdata), types); 441 ReadCustomDataTypes(::GlobalLock(hdata), ::GlobalSize(hdata), types);
409 ::GlobalUnlock(hdata); 442 ::GlobalUnlock(hdata);
410 } 443 }
411 444
412 void Clipboard::ReadText(ClipboardType type, base::string16* result) const { 445 void ClipboardWin::ReadText(ClipboardType type, base::string16* result) const {
413 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 446 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
414 if (!result) { 447 if (!result) {
415 NOTREACHED(); 448 NOTREACHED();
416 return; 449 return;
417 } 450 }
418 451
419 result->clear(); 452 result->clear();
420 453
421 // Acquire the clipboard. 454 // Acquire the clipboard.
422 ScopedClipboard clipboard; 455 ScopedClipboard clipboard;
423 if (!clipboard.Acquire(GetClipboardWindow())) 456 if (!clipboard.Acquire(GetClipboardWindow()))
424 return; 457 return;
425 458
426 HANDLE data = ::GetClipboardData(CF_UNICODETEXT); 459 HANDLE data = ::GetClipboardData(CF_UNICODETEXT);
427 if (!data) 460 if (!data)
428 return; 461 return;
429 462
430 result->assign(static_cast<const base::char16*>(::GlobalLock(data))); 463 result->assign(static_cast<const base::char16*>(::GlobalLock(data)));
431 ::GlobalUnlock(data); 464 ::GlobalUnlock(data);
432 } 465 }
433 466
434 void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const { 467 void ClipboardWin::ReadAsciiText(ClipboardType type,
468 std::string* result) const {
435 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 469 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
436 if (!result) { 470 if (!result) {
437 NOTREACHED(); 471 NOTREACHED();
438 return; 472 return;
439 } 473 }
440 474
441 result->clear(); 475 result->clear();
442 476
443 // Acquire the clipboard. 477 // Acquire the clipboard.
444 ScopedClipboard clipboard; 478 ScopedClipboard clipboard;
445 if (!clipboard.Acquire(GetClipboardWindow())) 479 if (!clipboard.Acquire(GetClipboardWindow()))
446 return; 480 return;
447 481
448 HANDLE data = ::GetClipboardData(CF_TEXT); 482 HANDLE data = ::GetClipboardData(CF_TEXT);
449 if (!data) 483 if (!data)
450 return; 484 return;
451 485
452 result->assign(static_cast<const char*>(::GlobalLock(data))); 486 result->assign(static_cast<const char*>(::GlobalLock(data)));
453 ::GlobalUnlock(data); 487 ::GlobalUnlock(data);
454 } 488 }
455 489
456 void Clipboard::ReadHTML(ClipboardType type, 490 void ClipboardWin::ReadHTML(ClipboardType type,
457 base::string16* markup, 491 base::string16* markup,
458 std::string* src_url, 492 std::string* src_url,
459 uint32* fragment_start, 493 uint32* fragment_start,
460 uint32* fragment_end) const { 494 uint32* fragment_end) const {
461 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 495 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
462 496
463 markup->clear(); 497 markup->clear();
464 // TODO(dcheng): Remove these checks, I don't think they should be optional. 498 // TODO(dcheng): Remove these checks, I don't think they should be optional.
465 DCHECK(src_url); 499 DCHECK(src_url);
466 if (src_url) 500 if (src_url)
467 src_url->clear(); 501 src_url->clear();
468 *fragment_start = 0; 502 *fragment_start = 0;
469 *fragment_end = 0; 503 *fragment_end = 0;
470 504
471 // Acquire the clipboard. 505 // Acquire the clipboard.
472 ScopedClipboard clipboard; 506 ScopedClipboard clipboard;
473 if (!clipboard.Acquire(GetClipboardWindow())) 507 if (!clipboard.Acquire(GetClipboardWindow()))
474 return; 508 return;
475 509
476 HANDLE data = ::GetClipboardData(GetHtmlFormatType().ToUINT()); 510 HANDLE data = ::GetClipboardData(GetHtmlFormatType().ToFormatEtc().cfFormat);
477 if (!data) 511 if (!data)
478 return; 512 return;
479 513
480 std::string cf_html(static_cast<const char*>(::GlobalLock(data))); 514 std::string cf_html(static_cast<const char*>(::GlobalLock(data)));
481 ::GlobalUnlock(data); 515 ::GlobalUnlock(data);
482 516
483 size_t html_start = std::string::npos; 517 size_t html_start = std::string::npos;
484 size_t start_index = std::string::npos; 518 size_t start_index = std::string::npos;
485 size_t end_index = std::string::npos; 519 size_t end_index = std::string::npos;
486 ClipboardUtil::CFHtmlExtractMetadata(cf_html, src_url, &html_start, 520 ClipboardUtil::CFHtmlExtractMetadata(cf_html, src_url, &html_start,
(...skipping 11 matching lines...) Expand all
498 532
499 std::vector<size_t> offsets; 533 std::vector<size_t> offsets;
500 offsets.push_back(start_index - html_start); 534 offsets.push_back(start_index - html_start);
501 offsets.push_back(end_index - html_start); 535 offsets.push_back(end_index - html_start);
502 markup->assign(base::UTF8ToUTF16AndAdjustOffsets(cf_html.data() + html_start, 536 markup->assign(base::UTF8ToUTF16AndAdjustOffsets(cf_html.data() + html_start,
503 &offsets)); 537 &offsets));
504 *fragment_start = base::checked_cast<uint32>(offsets[0]); 538 *fragment_start = base::checked_cast<uint32>(offsets[0]);
505 *fragment_end = base::checked_cast<uint32>(offsets[1]); 539 *fragment_end = base::checked_cast<uint32>(offsets[1]);
506 } 540 }
507 541
508 void Clipboard::ReadRTF(ClipboardType type, std::string* result) const { 542 void ClipboardWin::ReadRTF(ClipboardType type, std::string* result) const {
509 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 543 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
510 544
511 ReadData(GetRtfFormatType(), result); 545 ReadData(GetRtfFormatType(), result);
512 } 546 }
513 547
514 SkBitmap Clipboard::ReadImage(ClipboardType type) const { 548 SkBitmap ClipboardWin::ReadImage(ClipboardType type) const {
515 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 549 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
516 550
517 // Acquire the clipboard. 551 // Acquire the clipboard.
518 ScopedClipboard clipboard; 552 ScopedClipboard clipboard;
519 if (!clipboard.Acquire(GetClipboardWindow())) 553 if (!clipboard.Acquire(GetClipboardWindow()))
520 return SkBitmap(); 554 return SkBitmap();
521 555
522 // We use a DIB rather than a DDB here since ::GetObject() with the 556 // We use a DIB rather than a DDB here since ::GetObject() with the
523 // HBITMAP returned from ::GetClipboardData(CF_BITMAP) always reports a color 557 // HBITMAP returned from ::GetClipboardData(CF_BITMAP) always reports a color
524 // depth of 32bpp. 558 // depth of 32bpp.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 bool has_invalid_alpha_channel = bitmap->bmiHeader.biBitCount < 32 || 608 bool has_invalid_alpha_channel = bitmap->bmiHeader.biBitCount < 32 ||
575 BitmapHasInvalidPremultipliedColors(device_bitmap); 609 BitmapHasInvalidPremultipliedColors(device_bitmap);
576 if (has_invalid_alpha_channel) { 610 if (has_invalid_alpha_channel) {
577 MakeBitmapOpaque(device_bitmap); 611 MakeBitmapOpaque(device_bitmap);
578 } 612 }
579 } 613 }
580 614
581 return canvas.ExtractImageRep().sk_bitmap(); 615 return canvas.ExtractImageRep().sk_bitmap();
582 } 616 }
583 617
584 void Clipboard::ReadCustomData(ClipboardType clipboard_type, 618 void ClipboardWin::ReadCustomData(ClipboardType clipboard_type,
585 const base::string16& type, 619 const base::string16& type,
586 base::string16* result) const { 620 base::string16* result) const {
587 DCHECK_EQ(clipboard_type, CLIPBOARD_TYPE_COPY_PASTE); 621 DCHECK_EQ(clipboard_type, CLIPBOARD_TYPE_COPY_PASTE);
588 622
589 // Acquire the clipboard. 623 // Acquire the clipboard.
590 ScopedClipboard clipboard; 624 ScopedClipboard clipboard;
591 if (!clipboard.Acquire(GetClipboardWindow())) 625 if (!clipboard.Acquire(GetClipboardWindow()))
592 return; 626 return;
593 627
594 HANDLE hdata = ::GetClipboardData(GetWebCustomDataFormatType().ToUINT()); 628 HANDLE hdata =
629 ::GetClipboardData(GetWebCustomDataFormatType().ToFormatEtc().cfFormat);
595 if (!hdata) 630 if (!hdata)
596 return; 631 return;
597 632
598 ReadCustomDataForType(::GlobalLock(hdata), ::GlobalSize(hdata), type, result); 633 ReadCustomDataForType(::GlobalLock(hdata), ::GlobalSize(hdata), type, result);
599 ::GlobalUnlock(hdata); 634 ::GlobalUnlock(hdata);
600 } 635 }
601 636
602 void Clipboard::ReadBookmark(base::string16* title, std::string* url) const { 637 void ClipboardWin::ReadBookmark(base::string16* title, std::string* url) const {
603 if (title) 638 if (title)
604 title->clear(); 639 title->clear();
605 640
606 if (url) 641 if (url)
607 url->clear(); 642 url->clear();
608 643
609 // Acquire the clipboard. 644 // Acquire the clipboard.
610 ScopedClipboard clipboard; 645 ScopedClipboard clipboard;
611 if (!clipboard.Acquire(GetClipboardWindow())) 646 if (!clipboard.Acquire(GetClipboardWindow()))
612 return; 647 return;
613 648
614 HANDLE data = ::GetClipboardData(GetUrlWFormatType().ToUINT()); 649 HANDLE data = ::GetClipboardData(GetUrlWFormatType().ToFormatEtc().cfFormat);
615 if (!data) 650 if (!data)
616 return; 651 return;
617 652
618 base::string16 bookmark(static_cast<const base::char16*>(::GlobalLock(data))); 653 base::string16 bookmark(static_cast<const base::char16*>(::GlobalLock(data)));
619 ::GlobalUnlock(data); 654 ::GlobalUnlock(data);
620 655
621 ParseBookmarkClipboardFormat(bookmark, title, url); 656 ParseBookmarkClipboardFormat(bookmark, title, url);
622 } 657 }
623 658
624 void Clipboard::ReadData(const FormatType& format, std::string* result) const { 659 void ClipboardWin::ReadData(const FormatType& format,
660 std::string* result) const {
625 if (!result) { 661 if (!result) {
626 NOTREACHED(); 662 NOTREACHED();
627 return; 663 return;
628 } 664 }
629 665
630 ScopedClipboard clipboard; 666 ScopedClipboard clipboard;
631 if (!clipboard.Acquire(GetClipboardWindow())) 667 if (!clipboard.Acquire(GetClipboardWindow()))
632 return; 668 return;
633 669
634 HANDLE data = ::GetClipboardData(format.ToUINT()); 670 HANDLE data = ::GetClipboardData(format.ToFormatEtc().cfFormat);
635 if (!data) 671 if (!data)
636 return; 672 return;
637 673
638 result->assign(static_cast<const char*>(::GlobalLock(data)), 674 result->assign(static_cast<const char*>(::GlobalLock(data)),
639 ::GlobalSize(data)); 675 ::GlobalSize(data));
640 ::GlobalUnlock(data); 676 ::GlobalUnlock(data);
641 } 677 }
642 678
643 // static 679 void ClipboardWin::WriteObjects(ClipboardType type, const ObjectMap& objects) {
644 void Clipboard::ParseBookmarkClipboardFormat(const base::string16& bookmark,
645 base::string16* title,
646 std::string* url) {
647 const base::string16 kDelim = base::ASCIIToUTF16("\r\n");
648
649 const size_t title_end = bookmark.find_first_of(kDelim);
650 if (title)
651 title->assign(bookmark.substr(0, title_end));
652
653 if (url) {
654 const size_t url_start = bookmark.find_first_not_of(kDelim, title_end);
655 if (url_start != base::string16::npos) {
656 *url = base::UTF16ToUTF8(
657 bookmark.substr(url_start, base::string16::npos));
658 }
659 }
660 }
661
662 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) {
663 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); 680 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
664 681
665 ScopedClipboard clipboard; 682 ScopedClipboard clipboard;
666 if (!clipboard.Acquire(GetClipboardWindow())) 683 if (!clipboard.Acquire(GetClipboardWindow()))
667 return; 684 return;
668 685
669 ::EmptyClipboard(); 686 ::EmptyClipboard();
670 687
671 for (ObjectMap::const_iterator iter = objects.begin(); 688 for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end();
672 iter != objects.end(); ++iter) { 689 ++iter) {
673 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); 690 DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
674 } 691 }
675 } 692 }
676 693
677 void Clipboard::WriteText(const char* text_data, size_t text_len) { 694 void ClipboardWin::WriteText(const char* text_data, size_t text_len) {
678 base::string16 text; 695 base::string16 text;
679 base::UTF8ToUTF16(text_data, text_len, &text); 696 base::UTF8ToUTF16(text_data, text_len, &text);
680 HGLOBAL glob = CreateGlobalData(text); 697 HGLOBAL glob = CreateGlobalData(text);
681 698
682 WriteToClipboard(CF_UNICODETEXT, glob); 699 WriteToClipboard(CF_UNICODETEXT, glob);
683 } 700 }
684 701
685 void Clipboard::WriteHTML(const char* markup_data, 702 void ClipboardWin::WriteHTML(const char* markup_data,
686 size_t markup_len, 703 size_t markup_len,
687 const char* url_data, 704 const char* url_data,
688 size_t url_len) { 705 size_t url_len) {
689 std::string markup(markup_data, markup_len); 706 std::string markup(markup_data, markup_len);
690 std::string url; 707 std::string url;
691 708
692 if (url_len > 0) 709 if (url_len > 0)
693 url.assign(url_data, url_len); 710 url.assign(url_data, url_len);
694 711
695 std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url); 712 std::string html_fragment = ClipboardUtil::HtmlToCFHtml(markup, url);
696 HGLOBAL glob = CreateGlobalData(html_fragment); 713 HGLOBAL glob = CreateGlobalData(html_fragment);
697 714
698 WriteToClipboard(Clipboard::GetHtmlFormatType().ToUINT(), glob); 715 WriteToClipboard(Clipboard::GetHtmlFormatType().ToFormatEtc().cfFormat, glob);
699 } 716 }
700 717
701 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { 718 void ClipboardWin::WriteRTF(const char* rtf_data, size_t data_len) {
702 WriteData(GetRtfFormatType(), rtf_data, data_len); 719 WriteData(GetRtfFormatType(), rtf_data, data_len);
703 } 720 }
704 721
705 void Clipboard::WriteBookmark(const char* title_data, 722 void ClipboardWin::WriteBookmark(const char* title_data,
706 size_t title_len, 723 size_t title_len,
707 const char* url_data, 724 const char* url_data,
708 size_t url_len) { 725 size_t url_len) {
709 std::string bookmark(title_data, title_len); 726 std::string bookmark(title_data, title_len);
710 bookmark.append(1, L'\n'); 727 bookmark.append(1, L'\n');
711 bookmark.append(url_data, url_len); 728 bookmark.append(url_data, url_len);
712 729
713 base::string16 wide_bookmark = base::UTF8ToWide(bookmark); 730 base::string16 wide_bookmark = base::UTF8ToWide(bookmark);
714 HGLOBAL glob = CreateGlobalData(wide_bookmark); 731 HGLOBAL glob = CreateGlobalData(wide_bookmark);
715 732
716 WriteToClipboard(GetUrlWFormatType().ToUINT(), glob); 733 WriteToClipboard(GetUrlWFormatType().ToFormatEtc().cfFormat, glob);
717 } 734 }
718 735
719 void Clipboard::WriteWebSmartPaste() { 736 void ClipboardWin::WriteWebSmartPaste() {
720 DCHECK(clipboard_owner_->hwnd() != NULL); 737 DCHECK(clipboard_owner_->hwnd() != NULL);
721 ::SetClipboardData(GetWebKitSmartPasteFormatType().ToUINT(), NULL); 738 ::SetClipboardData(GetWebKitSmartPasteFormatType().ToFormatEtc().cfFormat,
739 NULL);
722 } 740 }
723 741
724 void Clipboard::WriteBitmap(const SkBitmap& bitmap) { 742 void ClipboardWin::WriteBitmap(const SkBitmap& bitmap) {
725 HDC dc = ::GetDC(NULL); 743 HDC dc = ::GetDC(NULL);
726 744
727 // This doesn't actually cost us a memcpy when the bitmap comes from the 745 // This doesn't actually cost us a memcpy when the bitmap comes from the
728 // renderer as we load it into the bitmap using setPixels which just sets a 746 // renderer as we load it into the bitmap using setPixels which just sets a
729 // pointer. Someone has to memcpy it into GDI, it might as well be us here. 747 // pointer. Someone has to memcpy it into GDI, it might as well be us here.
730 748
731 // TODO(darin): share data in gfx/bitmap_header.cc somehow 749 // TODO(darin): share data in gfx/bitmap_header.cc somehow
732 BITMAPINFO bm_info = {0}; 750 BITMAPINFO bm_info = {0};
733 bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 751 bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
734 bm_info.bmiHeader.biWidth = bitmap.width(); 752 bm_info.bmiHeader.biWidth = bitmap.width();
735 bm_info.bmiHeader.biHeight = -bitmap.height(); // sets vertical orientation 753 bm_info.bmiHeader.biHeight = -bitmap.height(); // sets vertical orientation
736 bm_info.bmiHeader.biPlanes = 1; 754 bm_info.bmiHeader.biPlanes = 1;
737 bm_info.bmiHeader.biBitCount = 32; 755 bm_info.bmiHeader.biBitCount = 32;
738 bm_info.bmiHeader.biCompression = BI_RGB; 756 bm_info.bmiHeader.biCompression = BI_RGB;
739 757
740 // ::CreateDIBSection allocates memory for us to copy our bitmap into. 758 // ::CreateDIBSection allocates memory for us to copy our bitmap into.
741 // Unfortunately, we can't write the created bitmap to the clipboard, 759 // Unfortunately, we can't write the created bitmap to the clipboard,
742 // (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx) 760 // (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx)
743 void *bits; 761 void* bits;
744 HBITMAP source_hbitmap = 762 HBITMAP source_hbitmap =
745 ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0); 763 ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0);
746 764
747 if (bits && source_hbitmap) { 765 if (bits && source_hbitmap) {
748 { 766 {
749 SkAutoLockPixels bitmap_lock(bitmap); 767 SkAutoLockPixels bitmap_lock(bitmap);
750 // Copy the bitmap out of shared memory and into GDI 768 // Copy the bitmap out of shared memory and into GDI
751 memcpy(bits, bitmap.getPixels(), bitmap.getSize()); 769 memcpy(bits, bitmap.getPixels(), bitmap.getSize());
752 } 770 }
753 771
754 // Now we have an HBITMAP, we can write it to the clipboard 772 // Now we have an HBITMAP, we can write it to the clipboard
755 WriteBitmapFromHandle(source_hbitmap, 773 WriteBitmapFromHandle(source_hbitmap,
756 gfx::Size(bitmap.width(), bitmap.height())); 774 gfx::Size(bitmap.width(), bitmap.height()));
757 } 775 }
758 776
759 ::DeleteObject(source_hbitmap); 777 ::DeleteObject(source_hbitmap);
760 ::ReleaseDC(NULL, dc); 778 ::ReleaseDC(NULL, dc);
761 } 779 }
762 780
763 void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, 781 void ClipboardWin::WriteData(const FormatType& format,
764 const gfx::Size& size) { 782 const char* data_data,
783 size_t data_len) {
784 HGLOBAL hdata = ::GlobalAlloc(GMEM_MOVEABLE, data_len);
785 if (!hdata)
786 return;
787
788 char* data = static_cast<char*>(::GlobalLock(hdata));
789 memcpy(data, data_data, data_len);
790 ::GlobalUnlock(data);
791 WriteToClipboard(format.ToFormatEtc().cfFormat, hdata);
792 }
793
794 void ClipboardWin::WriteBitmapFromHandle(HBITMAP source_hbitmap,
795 const gfx::Size& size) {
765 // We would like to just call ::SetClipboardData on the source_hbitmap, 796 // We would like to just call ::SetClipboardData on the source_hbitmap,
766 // but that bitmap might not be of a sort we can write to the clipboard. 797 // but that bitmap might not be of a sort we can write to the clipboard.
767 // For this reason, we create a new bitmap, copy the bits over, and then 798 // For this reason, we create a new bitmap, copy the bits over, and then
768 // write that to the clipboard. 799 // write that to the clipboard.
769 800
770 HDC dc = ::GetDC(NULL); 801 HDC dc = ::GetDC(NULL);
771 HDC compatible_dc = ::CreateCompatibleDC(NULL); 802 HDC compatible_dc = ::CreateCompatibleDC(NULL);
772 HDC source_dc = ::CreateCompatibleDC(NULL); 803 HDC source_dc = ::CreateCompatibleDC(NULL);
773 804
774 // This is the HBITMAP we will eventually write to the clipboard 805 // This is the HBITMAP we will eventually write to the clipboard
775 HBITMAP hbitmap = ::CreateCompatibleBitmap(dc, size.width(), size.height()); 806 HBITMAP hbitmap = ::CreateCompatibleBitmap(dc, size.width(), size.height());
776 if (!hbitmap) { 807 if (!hbitmap) {
777 // Failed to create the bitmap 808 // Failed to create the bitmap
778 ::DeleteDC(compatible_dc); 809 ::DeleteDC(compatible_dc);
779 ::DeleteDC(source_dc); 810 ::DeleteDC(source_dc);
780 ::ReleaseDC(NULL, dc); 811 ::ReleaseDC(NULL, dc);
781 return; 812 return;
782 } 813 }
783 814
784 HBITMAP old_hbitmap = (HBITMAP)SelectObject(compatible_dc, hbitmap); 815 HBITMAP old_hbitmap = (HBITMAP)SelectObject(compatible_dc, hbitmap);
785 HBITMAP old_source = (HBITMAP)SelectObject(source_dc, source_hbitmap); 816 HBITMAP old_source = (HBITMAP)SelectObject(source_dc, source_hbitmap);
786 817
787 // Now we need to blend it into an HBITMAP we can place on the clipboard 818 // Now we need to blend it into an HBITMAP we can place on the clipboard
788 BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; 819 BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
789 ::GdiAlphaBlend(compatible_dc, 0, 0, size.width(), size.height(), 820 ::GdiAlphaBlend(compatible_dc,
790 source_dc, 0, 0, size.width(), size.height(), bf); 821 0,
822 0,
823 size.width(),
824 size.height(),
825 source_dc,
826 0,
827 0,
828 size.width(),
829 size.height(),
830 bf);
791 831
792 // Clean up all the handles we just opened 832 // Clean up all the handles we just opened
793 ::SelectObject(compatible_dc, old_hbitmap); 833 ::SelectObject(compatible_dc, old_hbitmap);
794 ::SelectObject(source_dc, old_source); 834 ::SelectObject(source_dc, old_source);
795 ::DeleteObject(old_hbitmap); 835 ::DeleteObject(old_hbitmap);
796 ::DeleteObject(old_source); 836 ::DeleteObject(old_source);
797 ::DeleteDC(compatible_dc); 837 ::DeleteDC(compatible_dc);
798 ::DeleteDC(source_dc); 838 ::DeleteDC(source_dc);
799 ::ReleaseDC(NULL, dc); 839 ::ReleaseDC(NULL, dc);
800 840
801 WriteToClipboard(CF_BITMAP, hbitmap); 841 WriteToClipboard(CF_BITMAP, hbitmap);
802 } 842 }
803 843
804 void Clipboard::WriteData(const FormatType& format, 844 void ClipboardWin::WriteToClipboard(unsigned int format, HANDLE handle) {
805 const char* data_data,
806 size_t data_len) {
807 HGLOBAL hdata = ::GlobalAlloc(GMEM_MOVEABLE, data_len);
808 if (!hdata)
809 return;
810
811 char* data = static_cast<char*>(::GlobalLock(hdata));
812 memcpy(data, data_data, data_len);
813 ::GlobalUnlock(data);
814 WriteToClipboard(format.ToUINT(), hdata);
815 }
816
817 void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) {
818 DCHECK(clipboard_owner_->hwnd() != NULL); 845 DCHECK(clipboard_owner_->hwnd() != NULL);
819 if (handle && !::SetClipboardData(format, handle)) { 846 if (handle && !::SetClipboardData(format, handle)) {
820 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); 847 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError());
821 FreeData(format, handle); 848 FreeData(format, handle);
822 } 849 }
823 } 850 }
824 851
825 // static 852 HWND ClipboardWin::GetClipboardWindow() const {
826 void Clipboard::FreeData(unsigned int format, HANDLE data) {
827 if (format == CF_BITMAP)
828 ::DeleteObject(static_cast<HBITMAP>(data));
829 else
830 ::GlobalFree(data);
831 }
832
833 HWND Clipboard::GetClipboardWindow() const {
834 if (!clipboard_owner_) 853 if (!clipboard_owner_)
835 return NULL; 854 return NULL;
836 855
837 if (clipboard_owner_->hwnd() == NULL) 856 if (clipboard_owner_->hwnd() == NULL)
838 clipboard_owner_->Create(base::Bind(&ClipboardOwnerWndProc)); 857 clipboard_owner_->Create(base::Bind(&ClipboardOwnerWndProc));
839 858
840 return clipboard_owner_->hwnd(); 859 return clipboard_owner_->hwnd();
841 } 860 }
842 861
843 } // namespace ui 862 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/clipboard/clipboard_win.h ('k') | ui/base/ui_base.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698