| OLD | NEW |
| 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 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 0, 0, 0, 0, 0, | 142 0, 0, 0, 0, 0, |
| 143 HWND_MESSAGE, | 143 HWND_MESSAGE, |
| 144 0, 0, 0); | 144 0, 0, 0); |
| 145 } | 145 } |
| 146 | 146 |
| 147 Clipboard::~Clipboard() { | 147 Clipboard::~Clipboard() { |
| 148 ::DestroyWindow(clipboard_owner_); | 148 ::DestroyWindow(clipboard_owner_); |
| 149 clipboard_owner_ = NULL; | 149 clipboard_owner_ = NULL; |
| 150 } | 150 } |
| 151 | 151 |
| 152 void Clipboard::Clear() { | 152 void Clipboard::WriteObjects(const ObjectMap& objects) { |
| 153 // Acquire the clipboard. | 153 WriteObjects(objects, NULL); |
| 154 } |
| 155 |
| 156 void Clipboard::WriteObjects(const ObjectMap& objects, ProcessHandle process) { |
| 154 ClipboardLock lock; | 157 ClipboardLock lock; |
| 155 if (!lock.Acquire(clipboard_owner_)) | 158 if (!lock.Acquire(clipboard_owner_)) |
| 156 return; | 159 return; |
| 157 | 160 |
| 158 ::EmptyClipboard(); | 161 ::EmptyClipboard(); |
| 159 } | |
| 160 | 162 |
| 161 void Clipboard::WriteText(const std::wstring& text) { | 163 for (ObjectMap::const_iterator iter = objects.begin(); |
| 162 ClipboardLock lock; | 164 iter != objects.end(); ++iter) { |
| 163 if (!lock.Acquire(clipboard_owner_)) | 165 if (iter->first == CBF_SMBITMAP) |
| 164 return; | 166 WriteBitmapFromSharedMemory(&(iter->second[0].front()), |
| 165 | 167 &(iter->second[1].front()), |
| 166 HGLOBAL glob = CreateGlobalData(text); | 168 process); |
| 167 if (glob && !::SetClipboardData(CF_UNICODETEXT, glob)) | 169 else |
| 168 ::GlobalFree(glob); | 170 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 169 } | |
| 170 | |
| 171 void Clipboard::WriteHTML(const std::wstring& markup, | |
| 172 const std::string& url) { | |
| 173 // Acquire the clipboard. | |
| 174 ClipboardLock lock; | |
| 175 if (!lock.Acquire(clipboard_owner_)) | |
| 176 return; | |
| 177 | |
| 178 std::string html_fragment; | |
| 179 MarkupToHTMLClipboardFormat(markup, url, &html_fragment); | |
| 180 HGLOBAL glob = CreateGlobalData(html_fragment); | |
| 181 if (glob && !::SetClipboardData(GetHtmlFormatType(), glob)) { | |
| 182 ::GlobalFree(glob); | |
| 183 } | 171 } |
| 184 } | 172 } |
| 185 | 173 |
| 186 void Clipboard::WriteBookmark(const std::wstring& title, | 174 void Clipboard::WriteText(const char* text_data, size_t text_len) { |
| 187 const std::string& url) { | 175 std::wstring text; |
| 188 // Acquire the clipboard. | 176 UTF8ToWide(text_data, text_len, &text); |
| 189 ClipboardLock lock; | 177 HGLOBAL glob = CreateGlobalData(text); |
| 190 if (!lock.Acquire(clipboard_owner_)) | |
| 191 return; | |
| 192 | 178 |
| 193 std::wstring bookmark(title); | 179 WriteToClipboard(CF_UNICODETEXT, glob); |
| 194 bookmark.append(1, L'\n'); | |
| 195 bookmark.append(UTF8ToWide(url)); | |
| 196 HGLOBAL glob = CreateGlobalData(bookmark); | |
| 197 if (glob && !::SetClipboardData(GetUrlWFormatType(), glob)) { | |
| 198 ::GlobalFree(glob); | |
| 199 } | |
| 200 } | 180 } |
| 201 | 181 |
| 202 void Clipboard::WriteHyperlink(const std::wstring& title, | 182 void Clipboard::WriteHTML(const char* markup_data, |
| 203 const std::string& url) { | 183 size_t markup_len, |
| 204 // Write as a bookmark. | 184 const char* url_data, |
| 205 WriteBookmark(title, url); | 185 size_t url_len) { |
| 186 std::string html_fragment, |
| 187 markup(markup_data, markup_len), |
| 188 url; |
| 206 | 189 |
| 207 // Build the HTML link. | 190 if (url_len > 0) |
| 208 std::wstring link(L"<a href=\""); | 191 url.assign(url_data, url_len); |
| 209 link.append(UTF8ToWide(url)); | 192 |
| 210 link.append(L"\">"); | 193 MarkupToHTMLClipboardFormat(markup, url, &html_fragment); |
| 194 HGLOBAL glob = CreateGlobalData(html_fragment); |
| 195 |
| 196 WriteToClipboard(GetHtmlFormatType(), glob); |
| 197 } |
| 198 |
| 199 void Clipboard::WriteBookmark(const char* title_data, |
| 200 size_t title_len, |
| 201 const char* url_data, |
| 202 size_t url_len) { |
| 203 std::string bookmark(title_data, title_len); |
| 204 bookmark.append(1, L'\n'); |
| 205 bookmark.append(url_data, url_len); |
| 206 |
| 207 std::wstring wide_bookmark = UTF8ToWide(bookmark); |
| 208 HGLOBAL glob = CreateGlobalData(wide_bookmark); |
| 209 |
| 210 WriteToClipboard(GetUrlWFormatType(), glob); |
| 211 } |
| 212 |
| 213 void Clipboard::WriteHyperlink(const char* title_data, |
| 214 size_t title_len, |
| 215 const char* url_data, |
| 216 size_t url_len) { |
| 217 // Store as a bookmark. |
| 218 WriteBookmark(title_data, title_len, url_data, url_len); |
| 219 |
| 220 std::string title(title_data, title_len), |
| 221 url(url_data, url_len), |
| 222 link("<a href=\""); |
| 223 |
| 224 // Construct the hyperlink. |
| 225 link.append(url); |
| 226 link.append("\">"); |
| 211 link.append(title); | 227 link.append(title); |
| 212 link.append(L"</a>"); | 228 link.append("</a>"); |
| 213 | 229 |
| 214 // Write as an HTML link. | 230 // Store hyperlink as html. |
| 215 WriteHTML(link, std::string()); | 231 WriteHTML(link.c_str(), link.size(), NULL, 0); |
| 216 } | 232 } |
| 217 | 233 |
| 218 void Clipboard::WriteWebSmartPaste() { | 234 void Clipboard::WriteWebSmartPaste() { |
| 219 // Acquire the clipboard. | 235 ::SetClipboardData(GetWebKitSmartPasteFormatType(), NULL); |
| 220 ClipboardLock lock; | |
| 221 if (!lock.Acquire(clipboard_owner_)) | |
| 222 return; | |
| 223 | |
| 224 SetClipboardData(GetWebKitSmartPasteFormatType(), NULL); | |
| 225 } | 236 } |
| 226 | 237 |
| 227 void Clipboard::WriteBitmap(const void* pixels, const gfx::Size& size) { | 238 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { |
| 239 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); |
| 228 HDC dc = ::GetDC(NULL); | 240 HDC dc = ::GetDC(NULL); |
| 229 | 241 |
| 230 // This doesn't actually cost us a memcpy when the bitmap comes from the | 242 // This doesn't actually cost us a memcpy when the bitmap comes from the |
| 231 // renderer as we load it into the bitmap using setPixels which just sets a | 243 // renderer as we load it into the bitmap using setPixels which just sets a |
| 232 // pointer. Someone has to memcpy it into GDI, it might as well be us here. | 244 // pointer. Someone has to memcpy it into GDI, it might as well be us here. |
| 233 | 245 |
| 234 // TODO(darin): share data in gfx/bitmap_header.cc somehow | 246 // TODO(darin): share data in gfx/bitmap_header.cc somehow |
| 235 BITMAPINFO bm_info = {0}; | 247 BITMAPINFO bm_info = {0}; |
| 236 bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | 248 bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
| 237 bm_info.bmiHeader.biWidth = size.width(); | 249 bm_info.bmiHeader.biWidth = size->width(); |
| 238 bm_info.bmiHeader.biHeight = -size.height(); // sets vertical orientation | 250 bm_info.bmiHeader.biHeight = -size->height(); // sets vertical orientation |
| 239 bm_info.bmiHeader.biPlanes = 1; | 251 bm_info.bmiHeader.biPlanes = 1; |
| 240 bm_info.bmiHeader.biBitCount = 32; | 252 bm_info.bmiHeader.biBitCount = 32; |
| 241 bm_info.bmiHeader.biCompression = BI_RGB; | 253 bm_info.bmiHeader.biCompression = BI_RGB; |
| 242 | 254 |
| 243 // ::CreateDIBSection allocates memory for us to copy our bitmap into. | 255 // ::CreateDIBSection allocates memory for us to copy our bitmap into. |
| 244 // Unfortunately, we can't write the created bitmap to the clipboard, | 256 // Unfortunately, we can't write the created bitmap to the clipboard, |
| 245 // (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx) | 257 // (see http://msdn2.microsoft.com/en-us/library/ms532292.aspx) |
| 246 void *bits; | 258 void *bits; |
| 247 HBITMAP source_hbitmap = | 259 HBITMAP source_hbitmap = |
| 248 ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0); | 260 ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, &bits, NULL, 0); |
| 249 | 261 |
| 250 if (bits && source_hbitmap) { | 262 if (bits && source_hbitmap) { |
| 251 // Copy the bitmap out of shared memory and into GDI | 263 // Copy the bitmap out of shared memory and into GDI |
| 252 memcpy(bits, pixels, 4 * size.width() * size.height()); | 264 memcpy(bits, pixel_data, 4 * size->width() * size->height()); |
| 253 | 265 |
| 254 // Now we have an HBITMAP, we can write it to the clipboard | 266 // Now we have an HBITMAP, we can write it to the clipboard |
| 255 WriteBitmapFromHandle(source_hbitmap, size); | 267 WriteBitmapFromHandle(source_hbitmap, *size); |
| 256 } | 268 } |
| 257 | 269 |
| 258 ::DeleteObject(source_hbitmap); | 270 ::DeleteObject(source_hbitmap); |
| 259 ::ReleaseDC(NULL, dc); | 271 ::ReleaseDC(NULL, dc); |
| 260 } | 272 } |
| 261 | 273 |
| 262 void Clipboard::WriteBitmapFromSharedMemory(const SharedMemory& bitmap, | 274 void Clipboard::WriteBitmapFromSharedMemory(const char* bitmap_data, |
| 263 const gfx::Size& size) { | 275 const char* size_data, |
| 276 ProcessHandle process) { |
| 277 const SharedMemoryHandle* remote_bitmap_handle = |
| 278 reinterpret_cast<const SharedMemoryHandle*>(bitmap_data); |
| 279 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); |
| 280 |
| 281 SharedMemory bitmap(*remote_bitmap_handle, false, process); |
| 282 |
| 264 // TODO(darin): share data in gfx/bitmap_header.cc somehow | 283 // TODO(darin): share data in gfx/bitmap_header.cc somehow |
| 265 BITMAPINFO bm_info = {0}; | 284 BITMAPINFO bm_info = {0}; |
| 266 bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | 285 bm_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
| 267 bm_info.bmiHeader.biWidth = size.width(); | 286 bm_info.bmiHeader.biWidth = size->width(); |
| 268 bm_info.bmiHeader.biHeight = -size.height(); // Sets the vertical orientation | 287 bm_info.bmiHeader.biHeight = -size->height(); // Sets the vertical orientatio
n |
| 269 bm_info.bmiHeader.biPlanes = 1; | 288 bm_info.bmiHeader.biPlanes = 1; |
| 270 bm_info.bmiHeader.biBitCount = 32; | 289 bm_info.bmiHeader.biBitCount = 32; |
| 271 bm_info.bmiHeader.biCompression = BI_RGB; | 290 bm_info.bmiHeader.biCompression = BI_RGB; |
| 272 | 291 |
| 273 HDC dc = ::GetDC(NULL); | 292 HDC dc = ::GetDC(NULL); |
| 274 | 293 |
| 275 // We can create an HBITMAP directly using the shared memory handle, saving | 294 // We can create an HBITMAP directly using the shared memory handle, saving |
| 276 // a memcpy. | 295 // a memcpy. |
| 277 HBITMAP source_hbitmap = | 296 HBITMAP source_hbitmap = |
| 278 ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, NULL, bitmap.handle(), 0)
; | 297 ::CreateDIBSection(dc, &bm_info, DIB_RGB_COLORS, NULL, |
| 298 bitmap.handle(), 0); |
| 279 | 299 |
| 280 if (source_hbitmap) { | 300 if (source_hbitmap) { |
| 281 // Now we can write the HBITMAP to the clipboard | 301 // Now we can write the HBITMAP to the clipboard |
| 282 WriteBitmapFromHandle(source_hbitmap, size); | 302 WriteBitmapFromHandle(source_hbitmap, *size); |
| 283 } | 303 } |
| 284 | 304 |
| 285 ::DeleteObject(source_hbitmap); | 305 ::DeleteObject(source_hbitmap); |
| 286 ::ReleaseDC(NULL, dc); | 306 ::ReleaseDC(NULL, dc); |
| 287 } | 307 } |
| 288 | 308 |
| 289 void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, | 309 void Clipboard::WriteBitmapFromHandle(HBITMAP source_hbitmap, |
| 290 const gfx::Size& size) { | 310 const gfx::Size& size) { |
| 291 // Acquire the clipboard. | |
| 292 ClipboardLock lock; | |
| 293 if (!lock.Acquire(clipboard_owner_)) | |
| 294 return; | |
| 295 | |
| 296 // We would like to just call ::SetClipboardData on the source_hbitmap, | 311 // We would like to just call ::SetClipboardData on the source_hbitmap, |
| 297 // but that bitmap might not be of a sort we can write to the clipboard. | 312 // but that bitmap might not be of a sort we can write to the clipboard. |
| 298 // For this reason, we create a new bitmap, copy the bits over, and then | 313 // For this reason, we create a new bitmap, copy the bits over, and then |
| 299 // write that to the clipboard. | 314 // write that to the clipboard. |
| 300 | 315 |
| 301 HDC dc = ::GetDC(NULL); | 316 HDC dc = ::GetDC(NULL); |
| 302 HDC compatible_dc = ::CreateCompatibleDC(NULL); | 317 HDC compatible_dc = ::CreateCompatibleDC(NULL); |
| 303 HDC source_dc = ::CreateCompatibleDC(NULL); | 318 HDC source_dc = ::CreateCompatibleDC(NULL); |
| 304 | 319 |
| 305 // This is the HBITMAP we will eventually write to the clipboard | 320 // This is the HBITMAP we will eventually write to the clipboard |
| (...skipping 16 matching lines...) Expand all Loading... |
| 322 | 337 |
| 323 // Clean up all the handles we just opened | 338 // Clean up all the handles we just opened |
| 324 ::SelectObject(compatible_dc, old_hbitmap); | 339 ::SelectObject(compatible_dc, old_hbitmap); |
| 325 ::SelectObject(source_dc, old_source); | 340 ::SelectObject(source_dc, old_source); |
| 326 ::DeleteObject(old_hbitmap); | 341 ::DeleteObject(old_hbitmap); |
| 327 ::DeleteObject(old_source); | 342 ::DeleteObject(old_source); |
| 328 ::DeleteDC(compatible_dc); | 343 ::DeleteDC(compatible_dc); |
| 329 ::DeleteDC(source_dc); | 344 ::DeleteDC(source_dc); |
| 330 ::ReleaseDC(NULL, dc); | 345 ::ReleaseDC(NULL, dc); |
| 331 | 346 |
| 332 // Actually write the bitmap to the clipboard | 347 WriteToClipboard(CF_BITMAP, hbitmap); |
| 333 ::SetClipboardData(CF_BITMAP, hbitmap); | |
| 334 } | 348 } |
| 335 | 349 |
| 336 // Write a file or set of files to the clipboard in HDROP format. When the user | 350 // Write a file or set of files to the clipboard in HDROP format. When the user |
| 337 // invokes a paste command (in a Windows explorer shell, for example), the files | 351 // invokes a paste command (in a Windows explorer shell, for example), the files |
| 338 // will be copied to the paste location. | 352 // will be copied to the paste location. |
| 339 void Clipboard::WriteFile(const std::wstring& file) { | 353 void Clipboard::WriteFiles(const char* file_data, size_t file_len) { |
| 340 std::vector<std::wstring> files; | 354 std::wstring filenames(UTF8ToWide(std::string(file_data, file_len))); |
| 341 files.push_back(file); | 355 // Calculate the amount of space we'll need store the strings and |
| 342 WriteFiles(files); | 356 // a DROPFILES struct. |
| 343 } | 357 size_t bytes = sizeof(DROPFILES) + filenames.length() * sizeof(wchar_t); |
| 344 | |
| 345 void Clipboard::WriteFiles(const std::vector<std::wstring>& files) { | |
| 346 ClipboardLock lock; | |
| 347 if (!lock.Acquire(clipboard_owner_)) | |
| 348 return; | |
| 349 | |
| 350 // Calculate the amount of space we'll need store the strings: require | |
| 351 // NULL terminator between strings, and double null terminator at the end. | |
| 352 size_t bytes = sizeof(DROPFILES); | |
| 353 for (size_t i = 0; i < files.size(); ++i) | |
| 354 bytes += (files[i].length() + 1) * sizeof(wchar_t); | |
| 355 bytes += sizeof(wchar_t); | |
| 356 | 358 |
| 357 HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes); | 359 HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes); |
| 358 if (!hdata) | 360 if (!hdata) |
| 359 return; | 361 return; |
| 360 | 362 |
| 361 DROPFILES* drop_files = static_cast<DROPFILES*>(::GlobalLock(hdata)); | 363 char* data = static_cast<char*>(::GlobalLock(hdata)); |
| 364 DROPFILES* drop_files = reinterpret_cast<DROPFILES*>(data); |
| 362 drop_files->pFiles = sizeof(DROPFILES); | 365 drop_files->pFiles = sizeof(DROPFILES); |
| 363 drop_files->fWide = TRUE; | 366 drop_files->fWide = TRUE; |
| 364 BYTE* data = reinterpret_cast<BYTE*>(drop_files) + sizeof(DROPFILES); | |
| 365 | 367 |
| 366 // Copy the strings stored in 'files' with proper NULL separation. | 368 memcpy(data + sizeof DROPFILES, filenames.c_str(), |
| 367 wchar_t* data_pos = reinterpret_cast<wchar_t*>(data); | 369 filenames.length() * sizeof(wchar_t)); |
| 368 for (size_t i = 0; i < files.size(); ++i) { | |
| 369 size_t offset = files[i].length() + 1; | |
| 370 memcpy(data_pos, files[i].c_str(), offset * sizeof(wchar_t)); | |
| 371 data_pos += offset; | |
| 372 } | |
| 373 data_pos[0] = L'\0'; // Double NULL termination after the last string. | |
| 374 | 370 |
| 375 ::GlobalUnlock(hdata); | 371 ::GlobalUnlock(hdata); |
| 376 if (!::SetClipboardData(CF_HDROP, hdata)) | 372 WriteToClipboard(CF_HDROP, hdata); |
| 377 ::GlobalFree(hdata); | 373 } |
| 374 |
| 375 void Clipboard::WriteToClipboard(FormatType format, HANDLE handle) { |
| 376 if (handle && !::SetClipboardData(format, handle)) |
| 377 FreeData(format, handle); |
| 378 } | 378 } |
| 379 | 379 |
| 380 bool Clipboard::IsFormatAvailable(unsigned int format) const { | 380 bool Clipboard::IsFormatAvailable(unsigned int format) const { |
| 381 return ::IsClipboardFormatAvailable(format) != FALSE; | 381 return ::IsClipboardFormatAvailable(format) != FALSE; |
| 382 } | 382 } |
| 383 | 383 |
| 384 void Clipboard::ReadText(std::wstring* result) const { | 384 void Clipboard::ReadText(std::wstring* result) const { |
| 385 if (!result) { | 385 if (!result) { |
| 386 NOTREACHED(); | 386 NOTREACHED(); |
| 387 return; | 387 return; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 for (int i = 0; i < count; ++i) { | 507 for (int i = 0; i < count; ++i) { |
| 508 int size = ::DragQueryFile(drop, i, NULL, 0) + 1; | 508 int size = ::DragQueryFile(drop, i, NULL, 0) + 1; |
| 509 std::wstring file; | 509 std::wstring file; |
| 510 ::DragQueryFile(drop, i, WriteInto(&file, size), size); | 510 ::DragQueryFile(drop, i, WriteInto(&file, size), size); |
| 511 files->push_back(file); | 511 files->push_back(file); |
| 512 } | 512 } |
| 513 } | 513 } |
| 514 } | 514 } |
| 515 | 515 |
| 516 // static | 516 // static |
| 517 void Clipboard::MarkupToHTMLClipboardFormat(const std::wstring& markup, | 517 void Clipboard::MarkupToHTMLClipboardFormat(const std::string& markup, |
| 518 const std::string& src_url, | 518 const std::string& src_url, |
| 519 std::string* html_fragment) { | 519 std::string* html_fragment) { |
| 520 DCHECK(html_fragment); | 520 DCHECK(html_fragment); |
| 521 // Documentation for the CF_HTML format is available at | 521 // Documentation for the CF_HTML format is available at |
| 522 // http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp | 522 // http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp |
| 523 | 523 |
| 524 if (markup.empty()) { | 524 if (markup.empty()) { |
| 525 html_fragment->clear(); | 525 html_fragment->clear(); |
| 526 return; | 526 return; |
| 527 } | 527 } |
| 528 | 528 |
| 529 std::string markup_utf8 = WideToUTF8(markup); | |
| 530 | |
| 531 html_fragment->assign("Version:0.9"); | 529 html_fragment->assign("Version:0.9"); |
| 532 | 530 |
| 533 std::string start_html("\nStartHTML:"); | 531 std::string start_html("\nStartHTML:"); |
| 534 std::string end_html("\nEndHTML:"); | 532 std::string end_html("\nEndHTML:"); |
| 535 std::string start_fragment("\nStartFragment:"); | 533 std::string start_fragment("\nStartFragment:"); |
| 536 std::string end_fragment("\nEndFragment:"); | 534 std::string end_fragment("\nEndFragment:"); |
| 537 std::string source_url("\nSourceURL:"); | 535 std::string source_url("\nSourceURL:"); |
| 538 | 536 |
| 539 bool has_source_url = !src_url.empty() && | 537 bool has_source_url = !src_url.empty() && |
| 540 !StartsWithASCII(src_url, "about:", false); | 538 !StartsWithASCII(src_url, "about:", false); |
| 541 if (has_source_url) | 539 if (has_source_url) |
| 542 source_url.append(src_url); | 540 source_url.append(src_url); |
| 543 | 541 |
| 544 std::string start_markup("\n<HTML>\n<BODY>\n<!--StartFragment-->\n"); | 542 std::string start_markup("\n<HTML>\n<BODY>\n<!--StartFragment-->\n"); |
| 545 std::string end_markup("\n<!--EndFragment-->\n</BODY>\n</HTML>"); | 543 std::string end_markup("\n<!--EndFragment-->\n</BODY>\n</HTML>"); |
| 546 | 544 |
| 547 // calculate offsets | 545 // calculate offsets |
| 548 const size_t kMaxDigits = 10; // number of digits in UINT_MAX in base 10 | 546 const size_t kMaxDigits = 10; // number of digits in UINT_MAX in base 10 |
| 549 | 547 |
| 550 size_t start_html_offset, start_fragment_offset; | 548 size_t start_html_offset, start_fragment_offset; |
| 551 size_t end_fragment_offset, end_html_offset; | 549 size_t end_fragment_offset, end_html_offset; |
| 552 | 550 |
| 553 start_html_offset = html_fragment->length() + | 551 start_html_offset = html_fragment->length() + |
| 554 start_html.length() + end_html.length() + | 552 start_html.length() + end_html.length() + |
| 555 start_fragment.length() + end_fragment.length() + | 553 start_fragment.length() + end_fragment.length() + |
| 556 (has_source_url ? source_url.length() : 0) + | 554 (has_source_url ? source_url.length() : 0) + |
| 557 (4*kMaxDigits); | 555 (4*kMaxDigits); |
| 558 | 556 |
| 559 start_fragment_offset = start_html_offset + start_markup.length(); | 557 start_fragment_offset = start_html_offset + start_markup.length(); |
| 560 end_fragment_offset = start_fragment_offset + markup_utf8.length(); | 558 end_fragment_offset = start_fragment_offset + markup.length(); |
| 561 end_html_offset = end_fragment_offset + end_markup.length(); | 559 end_html_offset = end_fragment_offset + end_markup.length(); |
| 562 | 560 |
| 563 // fill in needed data | 561 // fill in needed data |
| 564 start_html.append(StringPrintf("%010u", start_html_offset)); | 562 start_html.append(StringPrintf("%010u", start_html_offset)); |
| 565 end_html.append(StringPrintf("%010u", end_html_offset)); | 563 end_html.append(StringPrintf("%010u", end_html_offset)); |
| 566 start_fragment.append(StringPrintf("%010u", start_fragment_offset)); | 564 start_fragment.append(StringPrintf("%010u", start_fragment_offset)); |
| 567 end_fragment.append(StringPrintf("%010u", end_fragment_offset)); | 565 end_fragment.append(StringPrintf("%010u", end_fragment_offset)); |
| 568 start_markup.append(markup_utf8); | 566 start_markup.append(markup); |
| 569 | 567 |
| 570 // create full html_fragment string from the fragments | 568 // create full html_fragment string from the fragments |
| 571 html_fragment->append(start_html); | 569 html_fragment->append(start_html); |
| 572 html_fragment->append(end_html); | 570 html_fragment->append(end_html); |
| 573 html_fragment->append(start_fragment); | 571 html_fragment->append(start_fragment); |
| 574 html_fragment->append(end_fragment); | 572 html_fragment->append(end_fragment); |
| 575 if (has_source_url) | 573 if (has_source_url) |
| 576 html_fragment->append(source_url); | 574 html_fragment->append(source_url); |
| 577 html_fragment->append(start_markup); | 575 html_fragment->append(start_markup); |
| 578 html_fragment->append(end_markup); | 576 html_fragment->append(end_markup); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 // static | 693 // static |
| 696 Clipboard::FormatType Clipboard::GetFileContentFormatZeroType() { | 694 Clipboard::FormatType Clipboard::GetFileContentFormatZeroType() { |
| 697 return ClipboardUtil::GetFileContentFormatZero()->cfFormat; | 695 return ClipboardUtil::GetFileContentFormatZero()->cfFormat; |
| 698 } | 696 } |
| 699 | 697 |
| 700 // static | 698 // static |
| 701 Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { | 699 Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { |
| 702 return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat; | 700 return ClipboardUtil::GetWebKitSmartPasteFormat()->cfFormat; |
| 703 } | 701 } |
| 704 | 702 |
| 703 // static |
| 704 void Clipboard::FreeData(FormatType format, HANDLE data) { |
| 705 if (format == CF_BITMAP) |
| 706 ::DeleteObject(static_cast<HBITMAP>(data)); |
| 707 else |
| 708 ::GlobalFree(data); |
| 709 } |
| OLD | NEW |