Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "ui/base/clipboard/clipboard.h" | 5 #include "ui/base/clipboard/clipboard.h" |
| 6 | 6 |
| 7 #include <X11/extensions/Xfixes.h> | 7 #include <X11/extensions/Xfixes.h> |
| 8 #include <X11/Xatom.h> | 8 #include <X11/Xatom.h> |
| 9 #include <list> | 9 #include <list> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 X11AtomCache* atom_cache() { return &atom_cache_; } | 232 X11AtomCache* atom_cache() { return &atom_cache_; } |
| 233 | 233 |
| 234 // Returns the X11 type that we pass to various XSelection functions for the | 234 // Returns the X11 type that we pass to various XSelection functions for the |
| 235 // given buffer. | 235 // given buffer. |
| 236 ::Atom LookupSelectionForBuffer(Buffer buffer) const; | 236 ::Atom LookupSelectionForBuffer(Buffer buffer) const; |
| 237 | 237 |
| 238 // Returns the object which is responsible for communication on |buffer|. | 238 // Returns the object which is responsible for communication on |buffer|. |
| 239 SelectionRequestor* GetSelectionRequestorForBuffer(Buffer buffer); | 239 SelectionRequestor* GetSelectionRequestorForBuffer(Buffer buffer); |
| 240 | 240 |
| 241 // Finds the SelectionFormatMap for the incoming selection atom. | 241 // Finds the SelectionFormatMap for the incoming selection atom. |
| 242 SelectionFormatMap* LookupStorageForAtom(::Atom atom); | 242 const SelectionFormatMap& LookupStorageForAtom(::Atom atom); |
| 243 | 243 |
| 244 // As we need to collect all the data types before we tell X11 that we own a | 244 // As we need to collect all the data types before we tell X11 that we own a |
| 245 // particular selection, we create a temporary clipboard mapping that | 245 // particular selection, we create a temporary clipboard mapping that |
| 246 // InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection, | 246 // InsertMapping writes to. Then we commit it in TakeOwnershipOfSelection, |
| 247 // where we save it in one of the clipboard data slots. | 247 // where we save it in one of the clipboard data slots. |
| 248 void CreateNewClipboardData(); | 248 void CreateNewClipboardData(); |
| 249 | 249 |
| 250 // Inserts a mapping into clipboard_data_. | 250 // Inserts a mapping into clipboard_data_. |
| 251 void InsertMapping(const std::string& key, char* data, size_t data_len); | 251 void InsertMapping(const std::string& key, |
| 252 const scoped_refptr<base::RefCountedMemory>& memory); | |
| 252 | 253 |
| 253 // Moves the temporary |clipboard_data_| to the long term data storage for | 254 // Moves the temporary |clipboard_data_| to the long term data storage for |
| 254 // |buffer|. | 255 // |buffer|. |
| 255 void TakeOwnershipOfSelection(Buffer buffer); | 256 void TakeOwnershipOfSelection(Buffer buffer); |
| 256 | 257 |
| 257 // Returns the first of |types| offered by the current selection holder in | 258 // Returns the first of |types| offered by the current selection holder in |
| 258 // |data_out|, or returns NULL if none of those types are available. | 259 // |data_out|, or returns NULL if none of those types are available. |
| 259 // | 260 // |
| 260 // If the selection holder is us, this call is synchronous and we pull | 261 // If the selection holder is us, this call is synchronous and we pull |
| 261 // the data out of |clipboard_selection_| or |primary_selection_|. If the | 262 // the data out of |clipboard_selection_| or |primary_selection_|. If the |
| 262 // selection holder is some other window, we spin up a nested message loop | 263 // selection holder is some other window, we spin up a nested message loop |
| 263 // and do the asynchronous dance with whatever application is holding the | 264 // and do the asynchronous dance with whatever application is holding the |
| 264 // selection. | 265 // selection. |
| 265 scoped_ptr<SelectionData> RequestAndWaitForTypes( | 266 ui::SelectionData RequestAndWaitForTypes(Buffer buffer, |
| 266 Buffer buffer, | 267 const std::vector< ::Atom>& types); |
| 267 const std::vector< ::Atom>& types); | |
| 268 | 268 |
| 269 // Retrieves the list of possible data types the current clipboard owner has. | 269 // Retrieves the list of possible data types the current clipboard owner has. |
| 270 // | 270 // |
| 271 // If the selection holder is us, this is synchronous, otherwise this runs a | 271 // If the selection holder is us, this is synchronous, otherwise this runs a |
| 272 // blocking message loop. | 272 // blocking message loop. |
| 273 TargetList WaitAndGetTargetsList(Buffer buffer); | 273 TargetList WaitAndGetTargetsList(Buffer buffer); |
| 274 | 274 |
| 275 // Returns a list of all text atoms that we handle. | 275 // Returns a list of all text atoms that we handle. |
| 276 std::vector< ::Atom> GetTextAtoms() const; | 276 std::vector< ::Atom> GetTextAtoms() const; |
| 277 | 277 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 292 // Input-only window used as a selection owner. | 292 // Input-only window used as a selection owner. |
| 293 ::Window x_window_; | 293 ::Window x_window_; |
| 294 | 294 |
| 295 X11AtomCache atom_cache_; | 295 X11AtomCache atom_cache_; |
| 296 | 296 |
| 297 // Objects which request and receive selection data. | 297 // Objects which request and receive selection data. |
| 298 SelectionRequestor clipboard_requestor_; | 298 SelectionRequestor clipboard_requestor_; |
| 299 SelectionRequestor primary_requestor_; | 299 SelectionRequestor primary_requestor_; |
| 300 | 300 |
| 301 // Temporary target map that we write to during DispatchObects. | 301 // Temporary target map that we write to during DispatchObects. |
| 302 scoped_ptr<SelectionFormatMap> clipboard_data_; | 302 SelectionFormatMap clipboard_data_; |
| 303 | 303 |
| 304 // Objects which offer selection data to other windows. | 304 // Objects which offer selection data to other windows. |
| 305 SelectionOwner clipboard_owner_; | 305 SelectionOwner clipboard_owner_; |
| 306 SelectionOwner primary_owner_; | 306 SelectionOwner primary_owner_; |
| 307 | 307 |
| 308 DISALLOW_COPY_AND_ASSIGN(AuraX11Details); | 308 DISALLOW_COPY_AND_ASSIGN(AuraX11Details); |
| 309 }; | 309 }; |
| 310 | 310 |
| 311 Clipboard::AuraX11Details::AuraX11Details() | 311 Clipboard::AuraX11Details::AuraX11Details() |
| 312 : x_display_(GetXDisplay()), | 312 : x_display_(GetXDisplay()), |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 342 } | 342 } |
| 343 | 343 |
| 344 ::Atom Clipboard::AuraX11Details::LookupSelectionForBuffer( | 344 ::Atom Clipboard::AuraX11Details::LookupSelectionForBuffer( |
| 345 Buffer buffer) const { | 345 Buffer buffer) const { |
| 346 if (buffer == BUFFER_STANDARD) | 346 if (buffer == BUFFER_STANDARD) |
| 347 return atom_cache_.GetAtom(kClipboard); | 347 return atom_cache_.GetAtom(kClipboard); |
| 348 else | 348 else |
| 349 return XA_PRIMARY; | 349 return XA_PRIMARY; |
| 350 } | 350 } |
| 351 | 351 |
| 352 SelectionFormatMap* Clipboard::AuraX11Details::LookupStorageForAtom( | 352 const SelectionFormatMap& Clipboard::AuraX11Details::LookupStorageForAtom( |
| 353 ::Atom atom) { | 353 ::Atom atom) { |
| 354 if (atom == XA_PRIMARY) | 354 if (atom == XA_PRIMARY) { |
| 355 return primary_owner_.selection_format_map(); | 355 return primary_owner_.selection_format_map(); |
| 356 else if (atom == atom_cache_.GetAtom(kClipboard)) | 356 } else { |
|
sky
2013/06/24 20:36:18
nit: style guide says no else when you have a retu
Elliot Glaysher
2013/06/24 20:54:35
Changed above instance, too, while I'm here.
| |
| 357 DCHECK_EQ(atom_cache_.GetAtom(kClipboard), atom); | |
| 357 return clipboard_owner_.selection_format_map(); | 358 return clipboard_owner_.selection_format_map(); |
| 358 else | 359 } |
| 359 return NULL; | |
| 360 } | 360 } |
| 361 | 361 |
| 362 ui::SelectionRequestor* | 362 ui::SelectionRequestor* |
| 363 Clipboard::AuraX11Details::GetSelectionRequestorForBuffer(Buffer buffer) { | 363 Clipboard::AuraX11Details::GetSelectionRequestorForBuffer(Buffer buffer) { |
| 364 if (buffer == BUFFER_STANDARD) | 364 if (buffer == BUFFER_STANDARD) |
| 365 return &clipboard_requestor_; | 365 return &clipboard_requestor_; |
| 366 else | 366 else |
| 367 return &primary_requestor_; | 367 return &primary_requestor_; |
| 368 } | 368 } |
| 369 | 369 |
| 370 void Clipboard::AuraX11Details::CreateNewClipboardData() { | 370 void Clipboard::AuraX11Details::CreateNewClipboardData() { |
| 371 clipboard_data_.reset(new SelectionFormatMap); | 371 clipboard_data_ = SelectionFormatMap(); |
| 372 } | 372 } |
| 373 | 373 |
| 374 void Clipboard::AuraX11Details::InsertMapping(const std::string& key, | 374 void Clipboard::AuraX11Details::InsertMapping( |
| 375 char* data, | 375 const std::string& key, |
| 376 size_t data_len) { | 376 const scoped_refptr<base::RefCountedMemory>& memory) { |
| 377 ::Atom atom_key = atom_cache_.GetAtom(key.c_str()); | 377 ::Atom atom_key = atom_cache_.GetAtom(key.c_str()); |
| 378 clipboard_data_->Insert(atom_key, data, data_len); | 378 clipboard_data_.Insert(atom_key, memory); |
| 379 } | 379 } |
| 380 | 380 |
| 381 void Clipboard::AuraX11Details::TakeOwnershipOfSelection(Buffer buffer) { | 381 void Clipboard::AuraX11Details::TakeOwnershipOfSelection(Buffer buffer) { |
| 382 if (buffer == BUFFER_STANDARD) | 382 if (buffer == BUFFER_STANDARD) |
| 383 return clipboard_owner_.TakeOwnershipOfSelection(clipboard_data_.Pass()); | 383 return clipboard_owner_.TakeOwnershipOfSelection(clipboard_data_); |
| 384 else | 384 else |
| 385 return primary_owner_.TakeOwnershipOfSelection(clipboard_data_.Pass()); | 385 return primary_owner_.TakeOwnershipOfSelection(clipboard_data_); |
| 386 } | 386 } |
| 387 | 387 |
| 388 scoped_ptr<SelectionData> Clipboard::AuraX11Details::RequestAndWaitForTypes( | 388 SelectionData Clipboard::AuraX11Details::RequestAndWaitForTypes( |
| 389 Buffer buffer, | 389 Buffer buffer, |
| 390 const std::vector< ::Atom>& types) { | 390 const std::vector< ::Atom>& types) { |
| 391 ::Atom selection_name = LookupSelectionForBuffer(buffer); | 391 ::Atom selection_name = LookupSelectionForBuffer(buffer); |
| 392 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { | 392 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { |
| 393 // We can local fastpath instead of playing the nested message loop game | 393 // We can local fastpath instead of playing the nested message loop game |
| 394 // with the X server. | 394 // with the X server. |
| 395 SelectionFormatMap* format_map = LookupStorageForAtom(selection_name); | 395 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); |
| 396 DCHECK(format_map); | |
| 397 | 396 |
| 398 for (std::vector< ::Atom>::const_iterator it = types.begin(); | 397 for (std::vector< ::Atom>::const_iterator it = types.begin(); |
| 399 it != types.end(); ++it) { | 398 it != types.end(); ++it) { |
| 400 SelectionFormatMap::const_iterator format_map_it = format_map->find(*it); | 399 SelectionFormatMap::const_iterator format_map_it = format_map.find(*it); |
| 401 if (format_map_it != format_map->end()) { | 400 if (format_map_it != format_map.end()) |
| 402 scoped_ptr<SelectionData> data_out(new SelectionData); | 401 return SelectionData(format_map_it->first, format_map_it->second); |
| 403 data_out->Set(format_map_it->first, format_map_it->second.first, | |
| 404 format_map_it->second.second, false); | |
| 405 return data_out.Pass(); | |
| 406 } | |
| 407 } | 402 } |
| 408 } else { | 403 } else { |
| 409 TargetList targets = WaitAndGetTargetsList(buffer); | 404 TargetList targets = WaitAndGetTargetsList(buffer); |
| 410 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); | 405 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); |
| 411 | 406 |
| 412 std::vector< ::Atom> intersection; | 407 std::vector< ::Atom> intersection; |
| 413 ui::GetAtomIntersection(targets.target_list(), types, &intersection); | 408 ui::GetAtomIntersection(targets.target_list(), types, &intersection); |
| 414 return receiver->RequestAndWaitForTypes(intersection); | 409 return receiver->RequestAndWaitForTypes(intersection); |
| 415 } | 410 } |
| 416 | 411 |
| 417 return scoped_ptr<SelectionData>(); | 412 return SelectionData(); |
| 418 } | 413 } |
| 419 | 414 |
| 420 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList( | 415 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList( |
| 421 Buffer buffer) { | 416 Buffer buffer) { |
| 422 ::Atom selection_name = LookupSelectionForBuffer(buffer); | 417 ::Atom selection_name = LookupSelectionForBuffer(buffer); |
| 423 std::vector< ::Atom> out; | 418 std::vector< ::Atom> out; |
| 424 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { | 419 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { |
| 425 // We can local fastpath and return the list of local targets. | 420 // We can local fastpath and return the list of local targets. |
| 426 SelectionFormatMap* format_map = LookupStorageForAtom(selection_name); | 421 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); |
| 427 DCHECK(format_map); | |
| 428 | 422 |
| 429 for (SelectionFormatMap::const_iterator it = format_map->begin(); | 423 for (SelectionFormatMap::const_iterator it = format_map.begin(); |
| 430 it != format_map->end(); ++it) { | 424 it != format_map.end(); ++it) { |
| 431 out.push_back(it->first); | 425 out.push_back(it->first); |
| 432 } | 426 } |
| 433 } else { | 427 } else { |
| 434 unsigned char* data = NULL; | 428 scoped_refptr<base::RefCountedMemory> data; |
| 435 size_t out_data_items = 0; | 429 size_t out_data_items = 0; |
| 436 ::Atom out_type = None; | 430 ::Atom out_type = None; |
| 437 | 431 |
| 438 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); | 432 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); |
| 439 if (receiver->PerformBlockingConvertSelection(atom_cache_.GetAtom(kTargets), | 433 if (receiver->PerformBlockingConvertSelection(atom_cache_.GetAtom(kTargets), |
| 440 &data, | 434 &data, |
| 441 NULL, | 435 NULL, |
| 442 &out_data_items, | 436 &out_data_items, |
| 443 &out_type)) { | 437 &out_type)) { |
| 444 ::Atom* atom_array = reinterpret_cast< ::Atom*>(data); | 438 const ::Atom* atom_array = reinterpret_cast<const ::Atom*>(data->front()); |
| 445 for (size_t i = 0; i < out_data_items; ++i) | 439 for (size_t i = 0; i < out_data_items; ++i) |
| 446 out.push_back(atom_array[i]); | 440 out.push_back(atom_array[i]); |
| 447 | |
| 448 XFree(data); | |
| 449 } else { | 441 } else { |
| 450 // There was no target list. Most Java apps doesn't offer a TARGETS list, | 442 // There was no target list. Most Java apps doesn't offer a TARGETS list, |
| 451 // even though they AWT to. They will offer individual text types if you | 443 // even though they AWT to. They will offer individual text types if you |
| 452 // ask. If this is the case we attempt to make sense of the contents as | 444 // ask. If this is the case we attempt to make sense of the contents as |
| 453 // text. This is pretty unfortunate since it means we have to actually | 445 // text. This is pretty unfortunate since it means we have to actually |
| 454 // copy the data to see if it is available, but at least this path | 446 // copy the data to see if it is available, but at least this path |
| 455 // shouldn't be hit for conforming programs. | 447 // shouldn't be hit for conforming programs. |
| 456 std::vector< ::Atom> types = GetTextAtoms(); | 448 std::vector< ::Atom> types = GetTextAtoms(); |
| 457 for (std::vector< ::Atom>::const_iterator it = types.begin(); | 449 for (std::vector< ::Atom>::const_iterator it = types.begin(); |
| 458 it != types.end(); ++it) { | 450 it != types.end(); ++it) { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 592 if (target_list.ContainsText()) | 584 if (target_list.ContainsText()) |
| 593 types->push_back(UTF8ToUTF16(kMimeTypeText)); | 585 types->push_back(UTF8ToUTF16(kMimeTypeText)); |
| 594 if (target_list.ContainsFormat(GetHtmlFormatType())) | 586 if (target_list.ContainsFormat(GetHtmlFormatType())) |
| 595 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); | 587 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); |
| 596 if (target_list.ContainsFormat(GetRtfFormatType())) | 588 if (target_list.ContainsFormat(GetRtfFormatType())) |
| 597 types->push_back(UTF8ToUTF16(kMimeTypeRTF)); | 589 types->push_back(UTF8ToUTF16(kMimeTypeRTF)); |
| 598 if (target_list.ContainsFormat(GetBitmapFormatType())) | 590 if (target_list.ContainsFormat(GetBitmapFormatType())) |
| 599 types->push_back(UTF8ToUTF16(kMimeTypePNG)); | 591 types->push_back(UTF8ToUTF16(kMimeTypePNG)); |
| 600 *contains_filenames = false; | 592 *contains_filenames = false; |
| 601 | 593 |
| 602 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 594 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 603 buffer, | 595 buffer, |
| 604 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); | 596 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); |
| 605 if (!data.get()) | 597 if (data.IsValid()) |
| 606 return; | 598 ReadCustomDataTypes(data.GetData(), data.GetSize(), types); |
| 607 | |
| 608 ReadCustomDataTypes(data->data(), data->size(), types); | |
| 609 } | 599 } |
| 610 | 600 |
| 611 void Clipboard::ReadText(Buffer buffer, string16* result) const { | 601 void Clipboard::ReadText(Buffer buffer, string16* result) const { |
| 612 DCHECK(CalledOnValidThread()); | 602 DCHECK(CalledOnValidThread()); |
| 613 | 603 |
| 614 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 604 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 615 buffer, aurax11_details_->GetTextAtoms())); | 605 buffer, aurax11_details_->GetTextAtoms())); |
| 616 if (data.get()) { | 606 if (data.IsValid()) { |
| 617 std::string text = data->GetText(); | 607 std::string text = data.GetText(); |
| 618 *result = UTF8ToUTF16(text); | 608 *result = UTF8ToUTF16(text); |
| 619 } | 609 } |
| 620 } | 610 } |
| 621 | 611 |
| 622 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const { | 612 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const { |
| 623 DCHECK(CalledOnValidThread()); | 613 DCHECK(CalledOnValidThread()); |
| 624 | 614 |
| 625 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 615 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 626 buffer, aurax11_details_->GetTextAtoms())); | 616 buffer, aurax11_details_->GetTextAtoms())); |
| 627 if (data.get()) | 617 if (data.IsValid()) |
| 628 result->assign(data->GetText()); | 618 result->assign(data.GetText()); |
| 629 } | 619 } |
| 630 | 620 |
| 631 // TODO(estade): handle different charsets. | 621 // TODO(estade): handle different charsets. |
| 632 // TODO(port): set *src_url. | 622 // TODO(port): set *src_url. |
| 633 void Clipboard::ReadHTML(Buffer buffer, | 623 void Clipboard::ReadHTML(Buffer buffer, |
| 634 string16* markup, | 624 string16* markup, |
| 635 std::string* src_url, | 625 std::string* src_url, |
| 636 uint32* fragment_start, | 626 uint32* fragment_start, |
| 637 uint32* fragment_end) const { | 627 uint32* fragment_end) const { |
| 638 DCHECK(CalledOnValidThread()); | 628 DCHECK(CalledOnValidThread()); |
| 639 markup->clear(); | 629 markup->clear(); |
| 640 if (src_url) | 630 if (src_url) |
| 641 src_url->clear(); | 631 src_url->clear(); |
| 642 *fragment_start = 0; | 632 *fragment_start = 0; |
| 643 *fragment_end = 0; | 633 *fragment_end = 0; |
| 644 | 634 |
| 645 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 635 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 646 buffer, aurax11_details_->GetAtomsForFormat(GetHtmlFormatType()))); | 636 buffer, aurax11_details_->GetAtomsForFormat(GetHtmlFormatType()))); |
| 647 if (!data.get()) | 637 if (data.IsValid()) { |
| 648 return; | 638 *markup = data.GetHtml(); |
| 649 | 639 |
| 650 *markup = data->GetHtml(); | 640 *fragment_start = 0; |
| 651 | 641 DCHECK(markup->length() <= kuint32max); |
| 652 *fragment_start = 0; | 642 *fragment_end = static_cast<uint32>(markup->length()); |
| 653 DCHECK(markup->length() <= kuint32max); | 643 } |
| 654 *fragment_end = static_cast<uint32>(markup->length()); | |
| 655 } | 644 } |
| 656 | 645 |
| 657 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { | 646 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { |
| 658 DCHECK(CalledOnValidThread()); | 647 DCHECK(CalledOnValidThread()); |
| 659 | 648 |
| 660 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 649 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 661 buffer, aurax11_details_->GetAtomsForFormat(GetRtfFormatType()))); | 650 buffer, aurax11_details_->GetAtomsForFormat(GetRtfFormatType()))); |
| 662 if (data.get()) | 651 if (data.IsValid()) |
| 663 data->AssignTo(result); | 652 data.AssignTo(result); |
| 664 } | 653 } |
| 665 | 654 |
| 666 SkBitmap Clipboard::ReadImage(Buffer buffer) const { | 655 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |
| 667 DCHECK(CalledOnValidThread()); | 656 DCHECK(CalledOnValidThread()); |
| 668 NOTIMPLEMENTED(); | 657 NOTIMPLEMENTED(); |
| 669 return SkBitmap(); | 658 return SkBitmap(); |
| 670 } | 659 } |
| 671 | 660 |
| 672 void Clipboard::ReadCustomData(Buffer buffer, | 661 void Clipboard::ReadCustomData(Buffer buffer, |
| 673 const string16& type, | 662 const string16& type, |
| 674 string16* result) const { | 663 string16* result) const { |
| 675 DCHECK(CalledOnValidThread()); | 664 DCHECK(CalledOnValidThread()); |
| 676 | 665 |
| 677 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 666 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 678 buffer, | 667 buffer, |
| 679 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); | 668 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); |
| 680 if (!data.get()) | 669 if (data.IsValid()) |
| 681 return; | 670 ReadCustomDataForType(data.GetData(), data.GetSize(), type, result); |
| 682 | |
| 683 ReadCustomDataForType(data->data(), data->size(), type, result); | |
| 684 } | 671 } |
| 685 | 672 |
| 686 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 673 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 687 DCHECK(CalledOnValidThread()); | 674 DCHECK(CalledOnValidThread()); |
| 688 // TODO(erg): This was left NOTIMPLEMENTED() in the gtk port too. | 675 // TODO(erg): This was left NOTIMPLEMENTED() in the gtk port too. |
| 689 NOTIMPLEMENTED(); | 676 NOTIMPLEMENTED(); |
| 690 } | 677 } |
| 691 | 678 |
| 692 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 679 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |
| 693 DCHECK(CalledOnValidThread()); | 680 DCHECK(CalledOnValidThread()); |
| 694 | 681 |
| 695 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 682 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 696 BUFFER_STANDARD, aurax11_details_->GetAtomsForFormat(format))); | 683 BUFFER_STANDARD, aurax11_details_->GetAtomsForFormat(format))); |
| 697 if (data.get()) | 684 if (data.IsValid()) |
| 698 data->AssignTo(result); | 685 data.AssignTo(result); |
| 699 } | 686 } |
| 700 | 687 |
| 701 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 688 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
| 702 DCHECK(CalledOnValidThread()); | 689 DCHECK(CalledOnValidThread()); |
| 703 if (buffer == BUFFER_STANDARD) | 690 if (buffer == BUFFER_STANDARD) |
| 704 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); | 691 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); |
| 705 else | 692 else |
| 706 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); | 693 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); |
| 707 } | 694 } |
| 708 | 695 |
| 709 void Clipboard::WriteText(const char* text_data, size_t text_len) { | 696 void Clipboard::WriteText(const char* text_data, size_t text_len) { |
| 710 char* data = new char[text_len]; | 697 std::string str(text_data, text_len); |
| 711 memcpy(data, text_data, text_len); | 698 scoped_refptr<base::RefCountedMemory> mem( |
| 699 base::RefCountedString::TakeString(&str)); | |
| 712 | 700 |
| 713 aurax11_details_->InsertMapping(kMimeTypeText, data, text_len); | 701 aurax11_details_->InsertMapping(kMimeTypeText, mem); |
| 714 aurax11_details_->InsertMapping(kText, data, text_len); | 702 aurax11_details_->InsertMapping(kText, mem); |
| 715 aurax11_details_->InsertMapping(kString, data, text_len); | 703 aurax11_details_->InsertMapping(kString, mem); |
| 716 aurax11_details_->InsertMapping(kUtf8String, data, text_len); | 704 aurax11_details_->InsertMapping(kUtf8String, mem); |
| 717 } | 705 } |
| 718 | 706 |
| 719 void Clipboard::WriteHTML(const char* markup_data, | 707 void Clipboard::WriteHTML(const char* markup_data, |
| 720 size_t markup_len, | 708 size_t markup_len, |
| 721 const char* url_data, | 709 const char* url_data, |
| 722 size_t url_len) { | 710 size_t url_len) { |
| 723 // TODO(estade): We need to expand relative links with |url_data|. | 711 // TODO(estade): We need to expand relative links with |url_data|. |
| 724 static const char* html_prefix = "<meta http-equiv=\"content-type\" " | 712 static const char* html_prefix = "<meta http-equiv=\"content-type\" " |
| 725 "content=\"text/html; charset=utf-8\">"; | 713 "content=\"text/html; charset=utf-8\">"; |
| 726 size_t html_prefix_len = strlen(html_prefix); | 714 std::string data = html_prefix; |
| 727 size_t total_len = html_prefix_len + markup_len + 1; | 715 data += std::string(markup_data, markup_len); |
| 716 // Some programs expect NULL-terminated data. See http://crbug.com/42624 | |
| 717 data += '\0'; | |
| 728 | 718 |
| 729 char* data = new char[total_len]; | 719 scoped_refptr<base::RefCountedMemory> mem( |
| 730 snprintf(data, total_len, "%s", html_prefix); | 720 base::RefCountedString::TakeString(&data)); |
| 731 memcpy(data + html_prefix_len, markup_data, markup_len); | 721 aurax11_details_->InsertMapping(kMimeTypeHTML, mem); |
| 732 // Some programs expect NULL-terminated data. See http://crbug.com/42624 | |
| 733 data[total_len - 1] = '\0'; | |
| 734 | |
| 735 aurax11_details_->InsertMapping(kMimeTypeHTML, data, total_len); | |
| 736 } | 722 } |
| 737 | 723 |
| 738 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { | 724 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { |
| 739 WriteData(GetRtfFormatType(), rtf_data, data_len); | 725 WriteData(GetRtfFormatType(), rtf_data, data_len); |
| 740 } | 726 } |
| 741 | 727 |
| 742 void Clipboard::WriteBookmark(const char* title_data, | 728 void Clipboard::WriteBookmark(const char* title_data, |
| 743 size_t title_len, | 729 size_t title_len, |
| 744 const char* url_data, | 730 const char* url_data, |
| 745 size_t url_len) { | 731 size_t url_len) { |
| 746 // Write as a mozilla url (UTF16: URL, newline, title). | 732 // Write as a mozilla url (UTF16: URL, newline, title). |
| 747 string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); | 733 string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); |
| 748 string16 title = UTF8ToUTF16(std::string(title_data, title_len)); | 734 string16 title = UTF8ToUTF16(std::string(title_data, title_len)); |
| 749 int data_len = 2 * (title.length() + url.length()); | |
| 750 | 735 |
| 751 char* data = new char[data_len]; | 736 std::vector<unsigned char> data; |
| 752 memcpy(data, url.data(), 2 * url.length()); | 737 ui::AddString16ToVector(url, &data); |
| 753 memcpy(data + 2 * url.length(), title.data(), 2 * title.length()); | 738 ui::AddString16ToVector(title, &data); |
| 754 aurax11_details_->InsertMapping(kMimeTypeMozillaURL, data, data_len); | 739 scoped_refptr<base::RefCountedMemory> mem( |
| 740 base::RefCountedBytes::TakeVector(&data)); | |
| 741 | |
| 742 aurax11_details_->InsertMapping(kMimeTypeMozillaURL, mem); | |
| 755 } | 743 } |
| 756 | 744 |
| 757 // Write an extra flavor that signifies WebKit was the last to modify the | 745 // Write an extra flavor that signifies WebKit was the last to modify the |
| 758 // pasteboard. This flavor has no data. | 746 // pasteboard. This flavor has no data. |
| 759 void Clipboard::WriteWebSmartPaste() { | 747 void Clipboard::WriteWebSmartPaste() { |
| 760 aurax11_details_->InsertMapping(kMimeTypeWebkitSmartPaste, NULL, 0); | 748 aurax11_details_->InsertMapping(kMimeTypeWebkitSmartPaste, |
| 749 scoped_refptr<base::RefCountedMemory>()); | |
| 761 } | 750 } |
| 762 | 751 |
| 763 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { | 752 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { |
| 764 // TODO(erg): I'm not sure if we should be writting BMP data here or | 753 // TODO(erg): I'm not sure if we should be writting BMP data here or |
| 765 // not. It's what the GTK port does, but I'm not sure it's the right thing to | 754 // not. It's what the GTK port does, but I'm not sure it's the right thing to |
| 766 // do. | 755 // do. |
| 767 NOTIMPLEMENTED(); | 756 NOTIMPLEMENTED(); |
| 768 } | 757 } |
| 769 | 758 |
| 770 void Clipboard::WriteData(const FormatType& format, | 759 void Clipboard::WriteData(const FormatType& format, |
| 771 const char* data_data, | 760 const char* data_data, |
| 772 size_t data_len) { | 761 size_t data_len) { |
| 773 // We assume that certain mapping types are only written by trusted code. | 762 // We assume that certain mapping types are only written by trusted code. |
| 774 // Therefore we must upkeep their integrity. | 763 // Therefore we must upkeep their integrity. |
| 775 if (format.Equals(GetBitmapFormatType())) | 764 if (format.Equals(GetBitmapFormatType())) |
| 776 return; | 765 return; |
| 777 char* data = new char[data_len]; | 766 |
| 778 memcpy(data, data_data, data_len); | 767 std::vector<unsigned char> bytes(data_data, data_data + data_len); |
| 779 aurax11_details_->InsertMapping(format.ToString(), data, data_len); | 768 scoped_refptr<base::RefCountedMemory> mem( |
| 769 base::RefCountedBytes::TakeVector(&bytes)); | |
| 770 aurax11_details_->InsertMapping(format.ToString(), mem); | |
| 780 } | 771 } |
| 781 | 772 |
| 782 // static | 773 // static |
| 783 Clipboard::FormatType Clipboard::GetFormatType( | 774 Clipboard::FormatType Clipboard::GetFormatType( |
| 784 const std::string& format_string) { | 775 const std::string& format_string) { |
| 785 return FormatType::Deserialize(format_string); | 776 return FormatType::Deserialize(format_string); |
| 786 } | 777 } |
| 787 | 778 |
| 788 // static | 779 // static |
| 789 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { | 780 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 848 return type; | 839 return type; |
| 849 } | 840 } |
| 850 | 841 |
| 851 // static | 842 // static |
| 852 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { | 843 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { |
| 853 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); | 844 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); |
| 854 return type; | 845 return type; |
| 855 } | 846 } |
| 856 | 847 |
| 857 } // namespace ui | 848 } // namespace ui |
| OLD | NEW |