OLD | NEW |
---|---|
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.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/basictypes.h" |
14 #include "base/bind.h" | |
14 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "base/memory/shared_memory.h" | 17 #include "base/memory/shared_memory.h" |
17 #include "base/message_loop.h" | 18 #include "base/message_loop.h" |
18 #include "base/safe_numerics.h" | 19 #include "base/safe_numerics.h" |
19 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
20 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
22 #include "base/strings/utf_offset_string_conversions.h" | 23 #include "base/strings/utf_offset_string_conversions.h" |
23 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" |
25 #include "base/win/message_window.h" | |
24 #include "base/win/scoped_gdi_object.h" | 26 #include "base/win/scoped_gdi_object.h" |
25 #include "base/win/scoped_hdc.h" | 27 #include "base/win/scoped_hdc.h" |
26 #include "base/win/wrapped_window_proc.h" | |
27 #include "third_party/skia/include/core/SkBitmap.h" | 28 #include "third_party/skia/include/core/SkBitmap.h" |
28 #include "ui/base/clipboard/clipboard_util_win.h" | 29 #include "ui/base/clipboard/clipboard_util_win.h" |
29 #include "ui/base/clipboard/custom_data_helper.h" | 30 #include "ui/base/clipboard/custom_data_helper.h" |
30 #include "ui/gfx/canvas.h" | 31 #include "ui/gfx/canvas.h" |
31 #include "ui/gfx/size.h" | 32 #include "ui/gfx/size.h" |
32 | 33 |
33 namespace ui { | 34 namespace ui { |
34 | 35 |
35 namespace { | 36 namespace { |
36 | 37 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 opened_ = false; | 88 opened_ = false; |
88 } else { | 89 } else { |
89 NOTREACHED(); | 90 NOTREACHED(); |
90 } | 91 } |
91 } | 92 } |
92 | 93 |
93 private: | 94 private: |
94 bool opened_; | 95 bool opened_; |
95 }; | 96 }; |
96 | 97 |
97 LRESULT CALLBACK ClipboardOwnerWndProc(HWND hwnd, | 98 bool ClipboardOwnerWndProc(UINT message, |
98 UINT message, | 99 WPARAM wparam, |
99 WPARAM wparam, | 100 LPARAM lparam, |
100 LPARAM lparam) { | 101 LRESULT* result) { |
101 LRESULT lresult = 0; | 102 LRESULT lresult = 0; |
dcheng
2013/06/27 17:56:23
Nit: Remove this, since it's unused.
alexeypa (please no reviews)
2013/06/27 17:58:55
Done.
| |
102 | 103 |
103 switch (message) { | 104 switch (message) { |
104 case WM_RENDERFORMAT: | 105 case WM_RENDERFORMAT: |
105 // This message comes when SetClipboardData was sent a null data handle | 106 // This message comes when SetClipboardData was sent a null data handle |
106 // and now it's come time to put the data on the clipboard. | 107 // and now it's come time to put the data on the clipboard. |
107 // We always set data, so there isn't a need to actually do anything here. | 108 // We always set data, so there isn't a need to actually do anything here. |
108 break; | 109 break; |
109 case WM_RENDERALLFORMATS: | 110 case WM_RENDERALLFORMATS: |
110 // This message comes when SetClipboardData was sent a null data handle | 111 // This message comes when SetClipboardData was sent a null data handle |
111 // and now this application is about to quit, so it must put data on | 112 // and now this application is about to quit, so it must put data on |
112 // the clipboard before it exits. | 113 // the clipboard before it exits. |
113 // We always set data, so there isn't a need to actually do anything here. | 114 // We always set data, so there isn't a need to actually do anything here. |
114 break; | 115 break; |
115 case WM_DRAWCLIPBOARD: | 116 case WM_DRAWCLIPBOARD: |
116 break; | 117 break; |
117 case WM_DESTROY: | 118 case WM_DESTROY: |
118 break; | 119 break; |
119 case WM_CHANGECBCHAIN: | 120 case WM_CHANGECBCHAIN: |
120 break; | 121 break; |
121 default: | 122 default: |
122 lresult = DefWindowProc(hwnd, message, wparam, lparam); | 123 return false; |
123 break; | |
124 } | 124 } |
125 return lresult; | 125 |
126 *result = 0; | |
127 return true; | |
126 } | 128 } |
127 | 129 |
128 template <typename charT> | 130 template <typename charT> |
129 HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) { | 131 HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) { |
130 HGLOBAL data = | 132 HGLOBAL data = |
131 ::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT))); | 133 ::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT))); |
132 if (data) { | 134 if (data) { |
133 charT* raw_data = static_cast<charT*>(::GlobalLock(data)); | 135 charT* raw_data = static_cast<charT*>(::GlobalLock(data)); |
134 memcpy(raw_data, str.data(), str.size() * sizeof(charT)); | 136 memcpy(raw_data, str.data(), str.size() * sizeof(charT)); |
135 raw_data[str.size()] = '\0'; | 137 raw_data[str.size()] = '\0'; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 NOTREACHED(); | 198 NOTREACHED(); |
197 return FormatType(); | 199 return FormatType(); |
198 } | 200 } |
199 return FormatType(clipboard_format); | 201 return FormatType(clipboard_format); |
200 } | 202 } |
201 | 203 |
202 bool Clipboard::FormatType::operator<(const FormatType& other) const { | 204 bool Clipboard::FormatType::operator<(const FormatType& other) const { |
203 return ToUINT() < other.ToUINT(); | 205 return ToUINT() < other.ToUINT(); |
204 } | 206 } |
205 | 207 |
206 Clipboard::Clipboard() : create_window_(false) { | 208 Clipboard::Clipboard() { |
207 if (base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI) { | 209 if (base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI) |
208 // Make a dummy HWND to be the clipboard's owner. | 210 clipboard_owner_.reset(new base::win::MessageWindow()); |
209 WNDCLASSEX window_class; | |
210 base::win::InitializeWindowClass( | |
211 L"ClipboardOwnerWindowClass", | |
212 &base::win::WrappedWindowProc<ClipboardOwnerWndProc>, | |
213 0, 0, 0, NULL, NULL, NULL, NULL, NULL, | |
214 &window_class); | |
215 ::RegisterClassEx(&window_class); | |
216 create_window_ = true; | |
217 } | |
218 | |
219 clipboard_owner_ = NULL; | |
220 } | 211 } |
221 | 212 |
222 Clipboard::~Clipboard() { | 213 Clipboard::~Clipboard() { |
223 if (clipboard_owner_) | |
224 ::DestroyWindow(clipboard_owner_); | |
225 clipboard_owner_ = NULL; | |
226 } | 214 } |
227 | 215 |
228 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { | 216 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { |
229 DCHECK_EQ(buffer, BUFFER_STANDARD); | 217 DCHECK_EQ(buffer, BUFFER_STANDARD); |
230 | 218 |
231 ScopedClipboard clipboard; | 219 ScopedClipboard clipboard; |
232 if (!clipboard.Acquire(GetClipboardWindow())) | 220 if (!clipboard.Acquire(GetClipboardWindow())) |
233 return; | 221 return; |
234 | 222 |
235 ::EmptyClipboard(); | 223 ::EmptyClipboard(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 bookmark.append(1, L'\n'); | 264 bookmark.append(1, L'\n'); |
277 bookmark.append(url_data, url_len); | 265 bookmark.append(url_data, url_len); |
278 | 266 |
279 string16 wide_bookmark = UTF8ToWide(bookmark); | 267 string16 wide_bookmark = UTF8ToWide(bookmark); |
280 HGLOBAL glob = CreateGlobalData(wide_bookmark); | 268 HGLOBAL glob = CreateGlobalData(wide_bookmark); |
281 | 269 |
282 WriteToClipboard(GetUrlWFormatType().ToUINT(), glob); | 270 WriteToClipboard(GetUrlWFormatType().ToUINT(), glob); |
283 } | 271 } |
284 | 272 |
285 void Clipboard::WriteWebSmartPaste() { | 273 void Clipboard::WriteWebSmartPaste() { |
286 DCHECK(clipboard_owner_); | 274 DCHECK(clipboard_owner_->hwnd() != NULL); |
287 ::SetClipboardData(GetWebKitSmartPasteFormatType().ToUINT(), NULL); | 275 ::SetClipboardData(GetWebKitSmartPasteFormatType().ToUINT(), NULL); |
288 } | 276 } |
289 | 277 |
290 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { | 278 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { |
291 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); | 279 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); |
292 HDC dc = ::GetDC(NULL); | 280 HDC dc = ::GetDC(NULL); |
293 | 281 |
294 // This doesn't actually cost us a memcpy when the bitmap comes from the | 282 // This doesn't actually cost us a memcpy when the bitmap comes from the |
295 // renderer as we load it into the bitmap using setPixels which just sets a | 283 // renderer as we load it into the bitmap using setPixels which just sets a |
296 // pointer. Someone has to memcpy it into GDI, it might as well be us here. | 284 // pointer. Someone has to memcpy it into GDI, it might as well be us here. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 if (!hdata) | 359 if (!hdata) |
372 return; | 360 return; |
373 | 361 |
374 char* data = static_cast<char*>(::GlobalLock(hdata)); | 362 char* data = static_cast<char*>(::GlobalLock(hdata)); |
375 memcpy(data, data_data, data_len); | 363 memcpy(data, data_data, data_len); |
376 ::GlobalUnlock(data); | 364 ::GlobalUnlock(data); |
377 WriteToClipboard(format.ToUINT(), hdata); | 365 WriteToClipboard(format.ToUINT(), hdata); |
378 } | 366 } |
379 | 367 |
380 void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { | 368 void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { |
381 DCHECK(clipboard_owner_); | 369 DCHECK(clipboard_owner_->hwnd() != NULL); |
382 if (handle && !::SetClipboardData(format, handle)) { | 370 if (handle && !::SetClipboardData(format, handle)) { |
383 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); | 371 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); |
384 FreeData(format, handle); | 372 FreeData(format, handle); |
385 } | 373 } |
386 } | 374 } |
387 | 375 |
388 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 376 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
389 DCHECK_EQ(buffer, BUFFER_STANDARD); | 377 DCHECK_EQ(buffer, BUFFER_STANDARD); |
390 return ::GetClipboardSequenceNumber(); | 378 return ::GetClipboardSequenceNumber(); |
391 } | 379 } |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
825 | 813 |
826 // static | 814 // static |
827 void Clipboard::FreeData(unsigned int format, HANDLE data) { | 815 void Clipboard::FreeData(unsigned int format, HANDLE data) { |
828 if (format == CF_BITMAP) | 816 if (format == CF_BITMAP) |
829 ::DeleteObject(static_cast<HBITMAP>(data)); | 817 ::DeleteObject(static_cast<HBITMAP>(data)); |
830 else | 818 else |
831 ::GlobalFree(data); | 819 ::GlobalFree(data); |
832 } | 820 } |
833 | 821 |
834 HWND Clipboard::GetClipboardWindow() const { | 822 HWND Clipboard::GetClipboardWindow() const { |
835 if (!clipboard_owner_ && create_window_) { | 823 if (!clipboard_owner_) |
836 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", | 824 return NULL; |
837 L"ClipboardOwnerWindow", | 825 |
838 0, 0, 0, 0, 0, | 826 if (clipboard_owner_->hwnd() == NULL) |
839 HWND_MESSAGE, | 827 clipboard_owner_->Create(base::Bind(&ClipboardOwnerWndProc)); |
840 0, 0, 0); | 828 |
841 } | 829 return clipboard_owner_->hwnd(); |
842 return clipboard_owner_; | |
843 } | 830 } |
844 | 831 |
845 } // namespace ui | 832 } // namespace ui |
OLD | NEW |