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 |