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

Side by Side Diff: base/clipboard_win.cc

Issue 9745: Clean up some confusing naming of ClipboardLock. It isn't a lock, and the wa... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 <shlobj.h> 8 #include <shlobj.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 10
11 #include "base/clipboard.h" 11 #include "base/clipboard.h"
12 12
13 #include "base/clipboard_util.h" 13 #include "base/clipboard_util.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 16
17 namespace { 17 namespace {
18 18
19 // A small object to ensure we close the clipboard after opening it. 19 // A scoper to manage acquiring and automatically releasing the clipboard.
20 class ClipboardLock { 20 class ScopedClipboard {
21 public: 21 public:
22 ClipboardLock() : we_own_the_lock_(false) { } 22 ScopedClipboard() : opened_(false) { }
23 23
24 ~ClipboardLock() { 24 ~ScopedClipboard() {
25 if (we_own_the_lock_) 25 if (opened_)
26 Release(); 26 Release();
27 } 27 }
28 28
29 bool Acquire(HWND owner) { 29 bool Acquire(HWND owner) {
30 // We shouldn't be calling this if we already own the clipboard lock.
31 DCHECK(!we_own_the_lock_);
32
33 // We already have the lock. We don't want to stomp on the other use.
34 if (we_own_the_lock_)
35 return false;
36
37 const int kMaxAttemptsToOpenClipboard = 5; 30 const int kMaxAttemptsToOpenClipboard = 5;
38 31
39 // Attempt to acquire the clipboard lock. This may fail if another process 32 if (opened_) {
40 // currently holds the lock. We're willing to try a few times in the hopes 33 NOTREACHED();
41 // of acquiring it. 34 return false;
35 }
36
37 // Attempt to open the clipboard, which will acquire the Windows clipboard
38 // lock. This may fail if another process currently holds this lock.
39 // We're willing to try a few times in the hopes of acquiring it.
42 // 40 //
43 // This turns out to be an issue when using remote desktop because the 41 // This turns out to be an issue when using remote desktop because the
44 // rdpclip.exe process likes to read what we've written to the clipboard and 42 // rdpclip.exe process likes to read what we've written to the clipboard and
45 // send it to the RDP client. If we open and close the clipboard in quick 43 // send it to the RDP client. If we open and close the clipboard in quick
46 // succession, we might be trying to open it while rdpclip.exe has it open, 44 // succession, we might be trying to open it while rdpclip.exe has it open,
47 // See Bug 815425. 45 // See Bug 815425.
48 // 46 //
49 // In fact, we believe we'll only spin this loop over remote desktop. In 47 // In fact, we believe we'll only spin this loop over remote desktop. In
50 // normal situations, the user is initiating clipboard operations and there 48 // normal situations, the user is initiating clipboard operations and there
51 // shouldn't be lock contention. 49 // shouldn't be contention.
52 50
53 for (int attempts = 0; attempts < kMaxAttemptsToOpenClipboard; ++attempts) { 51 for (int attempts = 0; attempts < kMaxAttemptsToOpenClipboard; ++attempts) {
52 // If we didn't manage to open the clipboard, sleep a bit and be hopeful.
53 if (attempts != 0)
54 ::Sleep(5);
55
54 if (::OpenClipboard(owner)) { 56 if (::OpenClipboard(owner)) {
55 we_own_the_lock_ = true; 57 opened_ = true;
56 return we_own_the_lock_; 58 return true;
57 } 59 }
58
59 // Having failed, we yield our timeslice to other processes. ::Yield seems
60 // to be insufficient here, so we sleep for 5 ms.
61 if (attempts < (kMaxAttemptsToOpenClipboard - 1))
62 ::Sleep(5);
63 } 60 }
64 61
65 // We failed to acquire the clipboard. 62 // We failed to acquire the clipboard.
66 return false; 63 return false;
67 } 64 }
68 65
69 void Release() { 66 void Release() {
70 // We should only be calling this if we already own the clipboard lock. 67 if (opened_) {
71 DCHECK(we_own_the_lock_); 68 ::CloseClipboard();
72 69 opened_ = false;
73 // We we don't have the lock, there is nothing to release. 70 } else {
74 if (!we_own_the_lock_) 71 NOTREACHED();
75 return; 72 }
76
77 ::CloseClipboard();
78 we_own_the_lock_ = false;
79 } 73 }
80 74
81 private: 75 private:
82 bool we_own_the_lock_; 76 bool opened_;
83 }; 77 };
84 78
85 LRESULT CALLBACK ClipboardOwnerWndProc(HWND hwnd, 79 LRESULT CALLBACK ClipboardOwnerWndProc(HWND hwnd,
86 UINT message, 80 UINT message,
87 WPARAM wparam, 81 WPARAM wparam,
88 LPARAM lparam) { 82 LPARAM lparam) {
89 LRESULT lresult = 0; 83 LRESULT lresult = 0;
90 84
91 switch(message) { 85 switch(message) {
92 case WM_RENDERFORMAT: 86 case WM_RENDERFORMAT:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 Clipboard::~Clipboard() { 141 Clipboard::~Clipboard() {
148 ::DestroyWindow(clipboard_owner_); 142 ::DestroyWindow(clipboard_owner_);
149 clipboard_owner_ = NULL; 143 clipboard_owner_ = NULL;
150 } 144 }
151 145
152 void Clipboard::WriteObjects(const ObjectMap& objects) { 146 void Clipboard::WriteObjects(const ObjectMap& objects) {
153 WriteObjects(objects, NULL); 147 WriteObjects(objects, NULL);
154 } 148 }
155 149
156 void Clipboard::WriteObjects(const ObjectMap& objects, ProcessHandle process) { 150 void Clipboard::WriteObjects(const ObjectMap& objects, ProcessHandle process) {
157 ClipboardLock lock; 151 ScopedClipboard clipboard;
158 if (!lock.Acquire(clipboard_owner_)) 152 if (!clipboard.Acquire(clipboard_owner_))
159 return; 153 return;
160 154
161 ::EmptyClipboard(); 155 ::EmptyClipboard();
162 156
163 for (ObjectMap::const_iterator iter = objects.begin(); 157 for (ObjectMap::const_iterator iter = objects.begin();
164 iter != objects.end(); ++iter) { 158 iter != objects.end(); ++iter) {
165 if (iter->first == CBF_SMBITMAP) 159 if (iter->first == CBF_SMBITMAP)
166 WriteBitmapFromSharedMemory(&(iter->second[0].front()), 160 WriteBitmapFromSharedMemory(&(iter->second[0].front()),
167 &(iter->second[1].front()), 161 &(iter->second[1].front()),
168 process); 162 process);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 377
384 void Clipboard::ReadText(std::wstring* result) const { 378 void Clipboard::ReadText(std::wstring* result) const {
385 if (!result) { 379 if (!result) {
386 NOTREACHED(); 380 NOTREACHED();
387 return; 381 return;
388 } 382 }
389 383
390 result->clear(); 384 result->clear();
391 385
392 // Acquire the clipboard. 386 // Acquire the clipboard.
393 ClipboardLock lock; 387 ScopedClipboard clipboard;
394 if (!lock.Acquire(clipboard_owner_)) 388 if (!clipboard.Acquire(clipboard_owner_))
395 return; 389 return;
396 390
397 HANDLE data = ::GetClipboardData(CF_UNICODETEXT); 391 HANDLE data = ::GetClipboardData(CF_UNICODETEXT);
398 if (!data) 392 if (!data)
399 return; 393 return;
400 394
401 result->assign(static_cast<const wchar_t*>(::GlobalLock(data))); 395 result->assign(static_cast<const wchar_t*>(::GlobalLock(data)));
402 ::GlobalUnlock(data); 396 ::GlobalUnlock(data);
403 } 397 }
404 398
405 void Clipboard::ReadAsciiText(std::string* result) const { 399 void Clipboard::ReadAsciiText(std::string* result) const {
406 if (!result) { 400 if (!result) {
407 NOTREACHED(); 401 NOTREACHED();
408 return; 402 return;
409 } 403 }
410 404
411 result->clear(); 405 result->clear();
412 406
413 // Acquire the clipboard. 407 // Acquire the clipboard.
414 ClipboardLock lock; 408 ScopedClipboard clipboard;
415 if (!lock.Acquire(clipboard_owner_)) 409 if (!clipboard.Acquire(clipboard_owner_))
416 return; 410 return;
417 411
418 HANDLE data = ::GetClipboardData(CF_TEXT); 412 HANDLE data = ::GetClipboardData(CF_TEXT);
419 if (!data) 413 if (!data)
420 return; 414 return;
421 415
422 result->assign(static_cast<const char*>(::GlobalLock(data))); 416 result->assign(static_cast<const char*>(::GlobalLock(data)));
423 ::GlobalUnlock(data); 417 ::GlobalUnlock(data);
424 } 418 }
425 419
426 void Clipboard::ReadHTML(std::wstring* markup, std::string* src_url) const { 420 void Clipboard::ReadHTML(std::wstring* markup, std::string* src_url) const {
427 if (markup) 421 if (markup)
428 markup->clear(); 422 markup->clear();
429 423
430 if (src_url) 424 if (src_url)
431 src_url->clear(); 425 src_url->clear();
432 426
433 // Acquire the clipboard. 427 // Acquire the clipboard.
434 ClipboardLock lock; 428 ScopedClipboard clipboard;
435 if (!lock.Acquire(clipboard_owner_)) 429 if (!clipboard.Acquire(clipboard_owner_))
436 return; 430 return;
437 431
438 HANDLE data = ::GetClipboardData(GetHtmlFormatType()); 432 HANDLE data = ::GetClipboardData(GetHtmlFormatType());
439 if (!data) 433 if (!data)
440 return; 434 return;
441 435
442 std::string html_fragment(static_cast<const char*>(::GlobalLock(data))); 436 std::string html_fragment(static_cast<const char*>(::GlobalLock(data)));
443 ::GlobalUnlock(data); 437 ::GlobalUnlock(data);
444 438
445 ParseHTMLClipboardFormat(html_fragment, markup, src_url); 439 ParseHTMLClipboardFormat(html_fragment, markup, src_url);
446 } 440 }
447 441
448 void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const { 442 void Clipboard::ReadBookmark(std::wstring* title, std::string* url) const {
449 if (title) 443 if (title)
450 title->clear(); 444 title->clear();
451 445
452 if (url) 446 if (url)
453 url->clear(); 447 url->clear();
454 448
455 // Acquire the clipboard. 449 // Acquire the clipboard.
456 ClipboardLock lock; 450 ScopedClipboard clipboard;
457 if (!lock.Acquire(clipboard_owner_)) 451 if (!clipboard.Acquire(clipboard_owner_))
458 return; 452 return;
459 453
460 HANDLE data = ::GetClipboardData(GetUrlWFormatType()); 454 HANDLE data = ::GetClipboardData(GetUrlWFormatType());
461 if (!data) 455 if (!data)
462 return; 456 return;
463 457
464 std::wstring bookmark(static_cast<const wchar_t*>(::GlobalLock(data))); 458 std::wstring bookmark(static_cast<const wchar_t*>(::GlobalLock(data)));
465 ::GlobalUnlock(data); 459 ::GlobalUnlock(data);
466 460
467 ParseBookmarkClipboardFormat(bookmark, title, url); 461 ParseBookmarkClipboardFormat(bookmark, title, url);
(...skipping 17 matching lines...) Expand all
485 479
486 // Read a set of files in HDROP format from the clipboard. 480 // Read a set of files in HDROP format from the clipboard.
487 void Clipboard::ReadFiles(std::vector<std::wstring>* files) const { 481 void Clipboard::ReadFiles(std::vector<std::wstring>* files) const {
488 if (!files) { 482 if (!files) {
489 NOTREACHED(); 483 NOTREACHED();
490 return; 484 return;
491 } 485 }
492 486
493 files->clear(); 487 files->clear();
494 488
495 ClipboardLock lock; 489 ScopedClipboard clipboard;
496 if (!lock.Acquire(clipboard_owner_)) 490 if (!clipboard.Acquire(clipboard_owner_))
497 return; 491 return;
498 492
499 HDROP drop = static_cast<HDROP>(::GetClipboardData(CF_HDROP)); 493 HDROP drop = static_cast<HDROP>(::GetClipboardData(CF_HDROP));
500 if (!drop) 494 if (!drop)
501 return; 495 return;
502 496
503 // Count of files in the HDROP. 497 // Count of files in the HDROP.
504 int count = ::DragQueryFile(drop, 0xffffffff, NULL, 0); 498 int count = ::DragQueryFile(drop, 0xffffffff, NULL, 0);
505 499
506 if (count) { 500 if (count) {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat; 694 return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat;
701 } 695 }
702 696
703 // static 697 // static
704 void Clipboard::FreeData(FormatType format, HANDLE data) { 698 void Clipboard::FreeData(FormatType format, HANDLE data) {
705 if (format == CF_BITMAP) 699 if (format == CF_BITMAP)
706 ::DeleteObject(static_cast<HBITMAP>(data)); 700 ::DeleteObject(static_cast<HBITMAP>(data));
707 else 701 else
708 ::GlobalFree(data); 702 ::GlobalFree(data);
709 } 703 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698