Index: base/clipboard_win.cc |
=================================================================== |
--- base/clipboard_win.cc (revision 8989) |
+++ base/clipboard_win.cc (working copy) |
@@ -12,6 +12,7 @@ |
#include "base/clipboard_util.h" |
#include "base/logging.h" |
+#include "base/message_loop.h" |
#include "base/string_util.h" |
namespace { |
@@ -82,7 +83,7 @@ |
LPARAM lparam) { |
LRESULT lresult = 0; |
- switch(message) { |
+ switch (message) { |
case WM_RENDERFORMAT: |
// This message comes when SetClipboardData was sent a null data handle |
// and now it's come time to put the data on the clipboard. |
@@ -122,14 +123,17 @@ |
} // namespace |
-Clipboard::Clipboard() { |
- // make a dummy HWND to be the clipboard's owner |
- WNDCLASSEX wcex = {0}; |
- wcex.cbSize = sizeof(WNDCLASSEX); |
- wcex.lpfnWndProc = ClipboardOwnerWndProc; |
- wcex.hInstance = GetModuleHandle(NULL); |
- wcex.lpszClassName = L"ClipboardOwnerWindowClass"; |
- ::RegisterClassEx(&wcex); |
+Clipboard::Clipboard() : create_window_(false) { |
+ if (MessageLoop::current()->type() == MessageLoop::TYPE_UI) { |
+ // Make a dummy HWND to be the clipboard's owner. |
+ WNDCLASSEX wcex = {0}; |
+ wcex.cbSize = sizeof(WNDCLASSEX); |
+ wcex.lpfnWndProc = ClipboardOwnerWndProc; |
+ wcex.hInstance = GetModuleHandle(NULL); |
+ wcex.lpszClassName = L"ClipboardOwnerWindowClass"; |
+ ::RegisterClassEx(&wcex); |
+ create_window_ = true; |
+ } |
clipboard_owner_ = NULL; |
} |
@@ -158,7 +162,7 @@ |
WriteBitmapFromSharedMemory(&(iter->second[0].front()), |
&(iter->second[1].front()), |
process); |
- else |
+ else |
DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
} |
} |
@@ -223,6 +227,7 @@ |
} |
void Clipboard::WriteWebSmartPaste() { |
+ DCHECK(clipboard_owner_); |
::SetClipboardData(GetWebKitSmartPasteFormatType(), NULL); |
} |
@@ -265,13 +270,15 @@ |
void Clipboard::WriteBitmapFromSharedMemory(const char* bitmap_data, |
const char* size_data, |
base::ProcessHandle process) { |
- const base::SharedMemoryHandle* remote_bitmap_handle = |
- reinterpret_cast<const base::SharedMemoryHandle*>(bitmap_data); |
const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); |
- base::SharedMemory bitmap(*remote_bitmap_handle, false, process); |
+ // bitmap_data has an encoded shared memory object. See |
+ // DuplicateRemoteHandles(). |
+ char* ptr = const_cast<char*>(bitmap_data); |
+ scoped_ptr<const base::SharedMemory> bitmap(* |
+ reinterpret_cast<const base::SharedMemory**>(ptr)); |
- // TODO(darin): share data in gfx/bitmap_header.cc somehow |
+ // TODO(darin): share data in gfx/bitmap_header.cc somehow. |
BITMAPINFO bm_info = {0}; |
bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
bm_info.bmiHeader.biWidth = size->width(); |
@@ -286,7 +293,7 @@ |
// a memcpy. |
HBITMAP source_hbitmap = |
::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, NULL, |
- bitmap.handle(), 0); |
+ bitmap->handle(), 0); |
if (source_hbitmap) { |
// Now we can write the HBITMAP to the clipboard |
@@ -364,8 +371,11 @@ |
} |
void Clipboard::WriteToClipboard(FormatType format, HANDLE handle) { |
- if (handle && !::SetClipboardData(format, handle)) |
+ DCHECK(clipboard_owner_); |
+ if (handle && !::SetClipboardData(format, handle)) { |
+ DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); |
FreeData(format, handle); |
+ } |
} |
bool Clipboard::IsFormatAvailable(unsigned int format) const { |
@@ -591,6 +601,30 @@ |
} |
// static |
+void Clipboard::DuplicateRemoteHandles(base::ProcessHandle process, |
+ ObjectMap* objects) { |
+ for (ObjectMap::iterator iter = objects->begin(); iter != objects->end(); |
+ ++iter) { |
+ if (iter->first == CBF_SMBITMAP) { |
+ // There is a shared memory handle encoded on the first ObjectMapParam. |
+ // Use it to open a local handle to the memory. |
+ char* bitmap_data = &(iter->second[0].front()); |
+ base::SharedMemoryHandle* remote_bitmap_handle = |
+ reinterpret_cast<base::SharedMemoryHandle*>(bitmap_data); |
+ |
+ base::SharedMemory* bitmap = new base::SharedMemory(*remote_bitmap_handle, |
+ false, process); |
+ |
+ // We store the object where the remote handle was located so it can |
+ // be retrieved by the UI thread (see WriteBitmapFromSharedMemory()). |
+ iter->second[0].clear(); |
+ for (size_t i = 0; i < sizeof(bitmap); i++) |
+ iter->second[0].push_back(reinterpret_cast<char*>(&bitmap)[i]); |
+ } |
+ } |
+} |
+ |
+// static |
Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { |
return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat; |
} |
@@ -604,7 +638,7 @@ |
} |
HWND Clipboard::GetClipboardWindow() const { |
- if (!clipboard_owner_) { |
+ if (!clipboard_owner_ && create_window_) { |
clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", |
L"ClipboardOwnerWindow", |
0, 0, 0, 0, 0, |