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

Side by Side Diff: base/clipboard_win.cc

Issue 9154: Rewrote the clipboard API to be more concurrent. Added a helper class to make... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/clipboard_unittest.cc ('k') | base/scoped_clipboard_writer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « base/clipboard_unittest.cc ('k') | base/scoped_clipboard_writer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698