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

Unified Diff: base/clipboard_win.cc

Issue 19733: Make sure that Clipboard operations that require dispatching... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 11 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 side-by-side diff with in-line comments
Download patch
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,
« base/clipboard.h ('K') | « base/clipboard_unittest.cc ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698