Index: base/clipboard_win.cc |
=================================================================== |
--- base/clipboard_win.cc (revision 4189) |
+++ base/clipboard_win.cc (working copy) |
@@ -149,82 +149,94 @@ |
clipboard_owner_ = NULL; |
} |
-void Clipboard::Clear() { |
- // Acquire the clipboard. |
+void Clipboard::WriteObjects(const ObjectMap& objects) { |
+ WriteObjects(objects, NULL); |
+} |
+ |
+void Clipboard::WriteObjects(const ObjectMap& objects, ProcessHandle process) { |
ClipboardLock lock; |
if (!lock.Acquire(clipboard_owner_)) |
return; |
::EmptyClipboard(); |
+ |
+ for (ObjectMap::const_iterator iter = objects.begin(); |
+ iter != objects.end(); ++iter) { |
+ if (iter->first == CBF_SMBITMAP) |
+ WriteBitmapFromSharedMemory(&(iter->second[0].front()), |
+ &(iter->second[1].front()), |
+ process); |
+ else |
+ DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
+ } |
} |
-void Clipboard::WriteText(const std::wstring& text) { |
- ClipboardLock lock; |
- if (!lock.Acquire(clipboard_owner_)) |
- return; |
+void Clipboard::WriteText(const char* text_data, size_t text_len) { |
+ std::wstring text; |
+ UTF8ToWide(text_data, text_len, &text); |
+ HGLOBAL glob = CreateGlobalData(text); |
- HGLOBAL glob = CreateGlobalData(text); |
- if (glob && !::SetClipboardData(CF_UNICODETEXT, glob)) |
- ::GlobalFree(glob); |
+ WriteToClipboard(CF_UNICODETEXT, glob); |
} |
-void Clipboard::WriteHTML(const std::wstring& markup, |
- const std::string& url) { |
- // Acquire the clipboard. |
- ClipboardLock lock; |
- if (!lock.Acquire(clipboard_owner_)) |
- return; |
+void Clipboard::WriteHTML(const char* markup_data, |
+ size_t markup_len, |
+ const char* url_data, |
+ size_t url_len) { |
+ std::string html_fragment, |
+ markup(markup_data, markup_len), |
+ url; |
- std::string html_fragment; |
+ if (url_len > 0) |
+ url.assign(url_data, url_len); |
+ |
MarkupToHTMLClipboardFormat(markup, url, &html_fragment); |
HGLOBAL glob = CreateGlobalData(html_fragment); |
- if (glob && !::SetClipboardData(GetHtmlFormatType(), glob)) { |
- ::GlobalFree(glob); |
- } |
+ |
+ WriteToClipboard(GetHtmlFormatType(), glob); |
} |
-void Clipboard::WriteBookmark(const std::wstring& title, |
- const std::string& url) { |
- // Acquire the clipboard. |
- ClipboardLock lock; |
- if (!lock.Acquire(clipboard_owner_)) |
- return; |
+void Clipboard::WriteBookmark(const char* title_data, |
+ size_t title_len, |
+ const char* url_data, |
+ size_t url_len) { |
+ std::string bookmark(title_data, title_len); |
+ bookmark.append(1, L'\n'); |
+ bookmark.append(url_data, url_len); |
- std::wstring bookmark(title); |
- bookmark.append(1, L'\n'); |
- bookmark.append(UTF8ToWide(url)); |
- HGLOBAL glob = CreateGlobalData(bookmark); |
- if (glob && !::SetClipboardData(GetUrlWFormatType(), glob)) { |
- ::GlobalFree(glob); |
- } |
+ std::wstring wide_bookmark = UTF8ToWide(bookmark); |
+ HGLOBAL glob = CreateGlobalData(wide_bookmark); |
+ |
+ WriteToClipboard(GetUrlWFormatType(), glob); |
} |
-void Clipboard::WriteHyperlink(const std::wstring& title, |
- const std::string& url) { |
- // Write as a bookmark. |
- WriteBookmark(title, url); |
+void Clipboard::WriteHyperlink(const char* title_data, |
+ size_t title_len, |
+ const char* url_data, |
+ size_t url_len) { |
+ // Store as a bookmark. |
+ WriteBookmark(title_data, title_len, url_data, url_len); |
- // Build the HTML link. |
- std::wstring link(L"<a href=\""); |
- link.append(UTF8ToWide(url)); |
- link.append(L"\">"); |
+ std::string title(title_data, title_len), |
+ url(url_data, url_len), |
+ link("<a href=\""); |
+ |
+ // Construct the hyperlink. |
+ link.append(url); |
+ link.append("\">"); |
link.append(title); |
- link.append(L"</a>"); |
+ link.append("</a>"); |
- // Write as an HTML link. |
- WriteHTML(link, std::string()); |
+ // Store hyperlink as html. |
+ WriteHTML(link.c_str(), link.size(), NULL, 0); |
} |
void Clipboard::WriteWebSmartPaste() { |
- // Acquire the clipboard. |
- ClipboardLock lock; |
- if (!lock.Acquire(clipboard_owner_)) |
- return; |
- |
- SetClipboardData(GetWebKitSmartPasteFormatType(), NULL); |
+ ::SetClipboardData(GetWebKitSmartPasteFormatType(), NULL); |
} |
-void Clipboard::WriteBitmap(const void* pixels, const gfx::Size& size) { |
+void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { |
+ const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); |
HDC dc = ::GetDC(NULL); |
// This doesn't actually cost us a memcpy when the bitmap comes from the |
@@ -234,8 +246,8 @@ |
// 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(); |
- bm_info.bmiHeader.biHeight = -size.height(); // sets vertical orientation |
+ bm_info.bmiHeader.biWidth = size->width(); |
+ bm_info.bmiHeader.biHeight = -size->height(); // sets vertical orientation |
bm_info.bmiHeader.biPlanes = 1; |
bm_info.bmiHeader.biBitCount = 32; |
bm_info.bmiHeader.biCompression = BI_RGB; |
@@ -249,23 +261,30 @@ |
if (bits && source_hbitmap) { |
// Copy the bitmap out of shared memory and into GDI |
- memcpy(bits, pixels, 4 * size.width() * size.height()); |
+ memcpy(bits, pixel_data, 4 * size->width() * size->height()); |
// Now we have an HBITMAP, we can write it to the clipboard |
- WriteBitmapFromHandle(source_hbitmap, size); |
+ WriteBitmapFromHandle(source_hbitmap, *size); |
} |
::DeleteObject(source_hbitmap); |
::ReleaseDC(NULL, dc); |
} |
-void Clipboard::WriteBitmapFromSharedMemory(const SharedMemory& bitmap, |
- const gfx::Size& size) { |
+void Clipboard::WriteBitmapFromSharedMemory(const char* bitmap_data, |
+ const char* size_data, |
+ ProcessHandle process) { |
+ const SharedMemoryHandle* remote_bitmap_handle = |
+ reinterpret_cast<const SharedMemoryHandle*>(bitmap_data); |
+ const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); |
+ |
+ SharedMemory bitmap(*remote_bitmap_handle, false, process); |
+ |
// 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(); |
- bm_info.bmiHeader.biHeight = -size.height(); // Sets the vertical orientation |
+ bm_info.bmiHeader.biWidth = size->width(); |
+ bm_info.bmiHeader.biHeight = -size->height(); // Sets the vertical orientation |
bm_info.bmiHeader.biPlanes = 1; |
bm_info.bmiHeader.biBitCount = 32; |
bm_info.bmiHeader.biCompression = BI_RGB; |
@@ -275,11 +294,12 @@ |
// We can create an HBITMAP directly using the shared memory handle, saving |
// a memcpy. |
HBITMAP source_hbitmap = |
- ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, NULL, bitmap.handle(), 0); |
+ ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, NULL, |
+ bitmap.handle(), 0); |
if (source_hbitmap) { |
// Now we can write the HBITMAP to the clipboard |
- WriteBitmapFromHandle(source_hbitmap, size); |
+ WriteBitmapFromHandle(source_hbitmap, *size); |
} |
::DeleteObject(source_hbitmap); |
@@ -288,11 +308,6 @@ |
void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, |
const gfx::Size& size) { |
- // Acquire the clipboard. |
- ClipboardLock lock; |
- if (!lock.Acquire(clipboard_owner_)) |
- return; |
- |
// We would like to just call ::SetClipboardData on the source_hbitmap, |
// but that bitmap might not be of a sort we can write to the clipboard. |
// For this reason, we create a new bitmap, copy the bits over, and then |
@@ -329,54 +344,39 @@ |
::DeleteDC(source_dc); |
::ReleaseDC(NULL, dc); |
- // Actually write the bitmap to the clipboard |
- ::SetClipboardData(CF_BITMAP, hbitmap); |
+ WriteToClipboard(CF_BITMAP, hbitmap); |
} |
// Write a file or set of files to the clipboard in HDROP format. When the user |
// invokes a paste command (in a Windows explorer shell, for example), the files |
// will be copied to the paste location. |
-void Clipboard::WriteFile(const std::wstring& file) { |
- std::vector<std::wstring> files; |
- files.push_back(file); |
- WriteFiles(files); |
-} |
+void Clipboard::WriteFiles(const char* file_data, size_t file_len) { |
+ std::wstring filenames(UTF8ToWide(std::string(file_data, file_len))); |
+ // Calculate the amount of space we'll need store the strings and |
+ // a DROPFILES struct. |
+ size_t bytes = sizeof(DROPFILES) + filenames.length() * sizeof(wchar_t); |
-void Clipboard::WriteFiles(const std::vector<std::wstring>& files) { |
- ClipboardLock lock; |
- if (!lock.Acquire(clipboard_owner_)) |
- return; |
- |
- // Calculate the amount of space we'll need store the strings: require |
- // NULL terminator between strings, and double null terminator at the end. |
- size_t bytes = sizeof(DROPFILES); |
- for (size_t i = 0; i < files.size(); ++i) |
- bytes += (files[i].length() + 1) * sizeof(wchar_t); |
- bytes += sizeof(wchar_t); |
- |
HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes); |
if (!hdata) |
return; |
- DROPFILES* drop_files = static_cast<DROPFILES*>(::GlobalLock(hdata)); |
+ char* data = static_cast<char*>(::GlobalLock(hdata)); |
+ DROPFILES* drop_files = reinterpret_cast<DROPFILES*>(data); |
drop_files->pFiles = sizeof(DROPFILES); |
drop_files->fWide = TRUE; |
- BYTE* data = reinterpret_cast<BYTE*>(drop_files) + sizeof(DROPFILES); |
- // Copy the strings stored in 'files' with proper NULL separation. |
- wchar_t* data_pos = reinterpret_cast<wchar_t*>(data); |
- for (size_t i = 0; i < files.size(); ++i) { |
- size_t offset = files[i].length() + 1; |
- memcpy(data_pos, files[i].c_str(), offset * sizeof(wchar_t)); |
- data_pos += offset; |
- } |
- data_pos[0] = L'\0'; // Double NULL termination after the last string. |
+ memcpy(data + sizeof DROPFILES, filenames.c_str(), |
+ filenames.length() * sizeof(wchar_t)); |
::GlobalUnlock(hdata); |
- if (!::SetClipboardData(CF_HDROP, hdata)) |
- ::GlobalFree(hdata); |
+ WriteToClipboard(CF_HDROP, hdata); |
} |
+void Clipboard::WriteToClipboard(FormatType format, HANDLE handle) { |
+ if (handle && !::SetClipboardData(format, handle)) |
+ FreeData(format, handle); |
+} |
+ |
bool Clipboard::IsFormatAvailable(unsigned int format) const { |
return ::IsClipboardFormatAvailable(format) != FALSE; |
} |
@@ -514,7 +514,7 @@ |
} |
// static |
-void Clipboard::MarkupToHTMLClipboardFormat(const std::wstring& markup, |
+void Clipboard::MarkupToHTMLClipboardFormat(const std::string& markup, |
const std::string& src_url, |
std::string* html_fragment) { |
DCHECK(html_fragment); |
@@ -526,8 +526,6 @@ |
return; |
} |
- std::string markup_utf8 = WideToUTF8(markup); |
- |
html_fragment->assign("Version:0.9"); |
std::string start_html("\nStartHTML:"); |
@@ -557,7 +555,7 @@ |
(4*kMaxDigits); |
start_fragment_offset = start_html_offset + start_markup.length(); |
- end_fragment_offset = start_fragment_offset + markup_utf8.length(); |
+ end_fragment_offset = start_fragment_offset + markup.length(); |
end_html_offset = end_fragment_offset + end_markup.length(); |
// fill in needed data |
@@ -565,7 +563,7 @@ |
end_html.append(StringPrintf("%010u", end_html_offset)); |
start_fragment.append(StringPrintf("%010u", start_fragment_offset)); |
end_fragment.append(StringPrintf("%010u", end_fragment_offset)); |
- start_markup.append(markup_utf8); |
+ start_markup.append(markup); |
// create full html_fragment string from the fragments |
html_fragment->append(start_html); |
@@ -702,3 +700,10 @@ |
return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat; |
} |
+// static |
+void Clipboard::FreeData(FormatType format, HANDLE data) { |
+ if (format == CF_BITMAP) |
+ ::DeleteObject(static_cast<HBITMAP>(data)); |
+ else |
+ ::GlobalFree(data); |
+} |