| 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 25 matching lines...) Expand all Loading... |
| 338 Clipboard::AuraX11Details::~AuraX11Details() { | 338 Clipboard::AuraX11Details::~AuraX11Details() { |
| 339 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); | 339 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(x_window_); |
| 340 | 340 |
| 341 XDestroyWindow(x_display_, x_window_); | 341 XDestroyWindow(x_display_, x_window_); |
| 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 |
| 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 |
| 357 return clipboard_owner_.selection_format_map(); | 357 DCHECK_EQ(atom_cache_.GetAtom(kClipboard), atom); |
| 358 else | 358 return clipboard_owner_.selection_format_map(); |
| 359 return NULL; | |
| 360 } | 359 } |
| 361 | 360 |
| 362 ui::SelectionRequestor* | 361 ui::SelectionRequestor* |
| 363 Clipboard::AuraX11Details::GetSelectionRequestorForBuffer(Buffer buffer) { | 362 Clipboard::AuraX11Details::GetSelectionRequestorForBuffer(Buffer buffer) { |
| 364 if (buffer == BUFFER_STANDARD) | 363 if (buffer == BUFFER_STANDARD) |
| 365 return &clipboard_requestor_; | 364 return &clipboard_requestor_; |
| 366 else | 365 else |
| 367 return &primary_requestor_; | 366 return &primary_requestor_; |
| 368 } | 367 } |
| 369 | 368 |
| 370 void Clipboard::AuraX11Details::CreateNewClipboardData() { | 369 void Clipboard::AuraX11Details::CreateNewClipboardData() { |
| 371 clipboard_data_.reset(new SelectionFormatMap); | 370 clipboard_data_ = SelectionFormatMap(); |
| 372 } | 371 } |
| 373 | 372 |
| 374 void Clipboard::AuraX11Details::InsertMapping(const std::string& key, | 373 void Clipboard::AuraX11Details::InsertMapping( |
| 375 char* data, | 374 const std::string& key, |
| 376 size_t data_len) { | 375 const scoped_refptr<base::RefCountedMemory>& memory) { |
| 377 ::Atom atom_key = atom_cache_.GetAtom(key.c_str()); | 376 ::Atom atom_key = atom_cache_.GetAtom(key.c_str()); |
| 378 clipboard_data_->Insert(atom_key, data, data_len); | 377 clipboard_data_.Insert(atom_key, memory); |
| 379 } | 378 } |
| 380 | 379 |
| 381 void Clipboard::AuraX11Details::TakeOwnershipOfSelection(Buffer buffer) { | 380 void Clipboard::AuraX11Details::TakeOwnershipOfSelection(Buffer buffer) { |
| 382 if (buffer == BUFFER_STANDARD) | 381 if (buffer == BUFFER_STANDARD) |
| 383 return clipboard_owner_.TakeOwnershipOfSelection(clipboard_data_.Pass()); | 382 return clipboard_owner_.TakeOwnershipOfSelection(clipboard_data_); |
| 384 else | 383 else |
| 385 return primary_owner_.TakeOwnershipOfSelection(clipboard_data_.Pass()); | 384 return primary_owner_.TakeOwnershipOfSelection(clipboard_data_); |
| 386 } | 385 } |
| 387 | 386 |
| 388 scoped_ptr<SelectionData> Clipboard::AuraX11Details::RequestAndWaitForTypes( | 387 SelectionData Clipboard::AuraX11Details::RequestAndWaitForTypes( |
| 389 Buffer buffer, | 388 Buffer buffer, |
| 390 const std::vector< ::Atom>& types) { | 389 const std::vector< ::Atom>& types) { |
| 391 ::Atom selection_name = LookupSelectionForBuffer(buffer); | 390 ::Atom selection_name = LookupSelectionForBuffer(buffer); |
| 392 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { | 391 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { |
| 393 // We can local fastpath instead of playing the nested message loop game | 392 // We can local fastpath instead of playing the nested message loop game |
| 394 // with the X server. | 393 // with the X server. |
| 395 SelectionFormatMap* format_map = LookupStorageForAtom(selection_name); | 394 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); |
| 396 DCHECK(format_map); | |
| 397 | 395 |
| 398 for (std::vector< ::Atom>::const_iterator it = types.begin(); | 396 for (std::vector< ::Atom>::const_iterator it = types.begin(); |
| 399 it != types.end(); ++it) { | 397 it != types.end(); ++it) { |
| 400 SelectionFormatMap::const_iterator format_map_it = format_map->find(*it); | 398 SelectionFormatMap::const_iterator format_map_it = format_map.find(*it); |
| 401 if (format_map_it != format_map->end()) { | 399 if (format_map_it != format_map.end()) |
| 402 scoped_ptr<SelectionData> data_out(new SelectionData); | 400 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 } | 401 } |
| 408 } else { | 402 } else { |
| 409 TargetList targets = WaitAndGetTargetsList(buffer); | 403 TargetList targets = WaitAndGetTargetsList(buffer); |
| 410 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); | 404 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); |
| 411 | 405 |
| 412 std::vector< ::Atom> intersection; | 406 std::vector< ::Atom> intersection; |
| 413 ui::GetAtomIntersection(targets.target_list(), types, &intersection); | 407 ui::GetAtomIntersection(targets.target_list(), types, &intersection); |
| 414 return receiver->RequestAndWaitForTypes(intersection); | 408 return receiver->RequestAndWaitForTypes(intersection); |
| 415 } | 409 } |
| 416 | 410 |
| 417 return scoped_ptr<SelectionData>(); | 411 return SelectionData(); |
| 418 } | 412 } |
| 419 | 413 |
| 420 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList( | 414 TargetList Clipboard::AuraX11Details::WaitAndGetTargetsList( |
| 421 Buffer buffer) { | 415 Buffer buffer) { |
| 422 ::Atom selection_name = LookupSelectionForBuffer(buffer); | 416 ::Atom selection_name = LookupSelectionForBuffer(buffer); |
| 423 std::vector< ::Atom> out; | 417 std::vector< ::Atom> out; |
| 424 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { | 418 if (XGetSelectionOwner(x_display_, selection_name) == x_window_) { |
| 425 // We can local fastpath and return the list of local targets. | 419 // We can local fastpath and return the list of local targets. |
| 426 SelectionFormatMap* format_map = LookupStorageForAtom(selection_name); | 420 const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name); |
| 427 DCHECK(format_map); | |
| 428 | 421 |
| 429 for (SelectionFormatMap::const_iterator it = format_map->begin(); | 422 for (SelectionFormatMap::const_iterator it = format_map.begin(); |
| 430 it != format_map->end(); ++it) { | 423 it != format_map.end(); ++it) { |
| 431 out.push_back(it->first); | 424 out.push_back(it->first); |
| 432 } | 425 } |
| 433 } else { | 426 } else { |
| 434 unsigned char* data = NULL; | 427 scoped_refptr<base::RefCountedMemory> data; |
| 435 size_t out_data_items = 0; | 428 size_t out_data_items = 0; |
| 436 ::Atom out_type = None; | 429 ::Atom out_type = None; |
| 437 | 430 |
| 438 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); | 431 SelectionRequestor* receiver = GetSelectionRequestorForBuffer(buffer); |
| 439 if (receiver->PerformBlockingConvertSelection(atom_cache_.GetAtom(kTargets), | 432 if (receiver->PerformBlockingConvertSelection(atom_cache_.GetAtom(kTargets), |
| 440 &data, | 433 &data, |
| 441 NULL, | 434 NULL, |
| 442 &out_data_items, | 435 &out_data_items, |
| 443 &out_type)) { | 436 &out_type)) { |
| 444 ::Atom* atom_array = reinterpret_cast< ::Atom*>(data); | 437 const ::Atom* atom_array = reinterpret_cast<const ::Atom*>(data->front()); |
| 445 for (size_t i = 0; i < out_data_items; ++i) | 438 for (size_t i = 0; i < out_data_items; ++i) |
| 446 out.push_back(atom_array[i]); | 439 out.push_back(atom_array[i]); |
| 447 | |
| 448 XFree(data); | |
| 449 } else { | 440 } else { |
| 450 // There was no target list. Most Java apps doesn't offer a TARGETS list, | 441 // 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 | 442 // 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 | 443 // 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 | 444 // 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 | 445 // copy the data to see if it is available, but at least this path |
| 455 // shouldn't be hit for conforming programs. | 446 // shouldn't be hit for conforming programs. |
| 456 std::vector< ::Atom> types = GetTextAtoms(); | 447 std::vector< ::Atom> types = GetTextAtoms(); |
| 457 for (std::vector< ::Atom>::const_iterator it = types.begin(); | 448 for (std::vector< ::Atom>::const_iterator it = types.begin(); |
| 458 it != types.end(); ++it) { | 449 it != types.end(); ++it) { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 if (target_list.ContainsText()) | 583 if (target_list.ContainsText()) |
| 593 types->push_back(UTF8ToUTF16(kMimeTypeText)); | 584 types->push_back(UTF8ToUTF16(kMimeTypeText)); |
| 594 if (target_list.ContainsFormat(GetHtmlFormatType())) | 585 if (target_list.ContainsFormat(GetHtmlFormatType())) |
| 595 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); | 586 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); |
| 596 if (target_list.ContainsFormat(GetRtfFormatType())) | 587 if (target_list.ContainsFormat(GetRtfFormatType())) |
| 597 types->push_back(UTF8ToUTF16(kMimeTypeRTF)); | 588 types->push_back(UTF8ToUTF16(kMimeTypeRTF)); |
| 598 if (target_list.ContainsFormat(GetBitmapFormatType())) | 589 if (target_list.ContainsFormat(GetBitmapFormatType())) |
| 599 types->push_back(UTF8ToUTF16(kMimeTypePNG)); | 590 types->push_back(UTF8ToUTF16(kMimeTypePNG)); |
| 600 *contains_filenames = false; | 591 *contains_filenames = false; |
| 601 | 592 |
| 602 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 593 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 603 buffer, | 594 buffer, |
| 604 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); | 595 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); |
| 605 if (!data.get()) | 596 if (data.IsValid()) |
| 606 return; | 597 ReadCustomDataTypes(data.GetData(), data.GetSize(), types); |
| 607 | |
| 608 ReadCustomDataTypes(data->data(), data->size(), types); | |
| 609 } | 598 } |
| 610 | 599 |
| 611 void Clipboard::ReadText(Buffer buffer, string16* result) const { | 600 void Clipboard::ReadText(Buffer buffer, string16* result) const { |
| 612 DCHECK(CalledOnValidThread()); | 601 DCHECK(CalledOnValidThread()); |
| 613 | 602 |
| 614 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 603 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 615 buffer, aurax11_details_->GetTextAtoms())); | 604 buffer, aurax11_details_->GetTextAtoms())); |
| 616 if (data.get()) { | 605 if (data.IsValid()) { |
| 617 std::string text = data->GetText(); | 606 std::string text = data.GetText(); |
| 618 *result = UTF8ToUTF16(text); | 607 *result = UTF8ToUTF16(text); |
| 619 } | 608 } |
| 620 } | 609 } |
| 621 | 610 |
| 622 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const { | 611 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const { |
| 623 DCHECK(CalledOnValidThread()); | 612 DCHECK(CalledOnValidThread()); |
| 624 | 613 |
| 625 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 614 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 626 buffer, aurax11_details_->GetTextAtoms())); | 615 buffer, aurax11_details_->GetTextAtoms())); |
| 627 if (data.get()) | 616 if (data.IsValid()) |
| 628 result->assign(data->GetText()); | 617 result->assign(data.GetText()); |
| 629 } | 618 } |
| 630 | 619 |
| 631 // TODO(estade): handle different charsets. | 620 // TODO(estade): handle different charsets. |
| 632 // TODO(port): set *src_url. | 621 // TODO(port): set *src_url. |
| 633 void Clipboard::ReadHTML(Buffer buffer, | 622 void Clipboard::ReadHTML(Buffer buffer, |
| 634 string16* markup, | 623 string16* markup, |
| 635 std::string* src_url, | 624 std::string* src_url, |
| 636 uint32* fragment_start, | 625 uint32* fragment_start, |
| 637 uint32* fragment_end) const { | 626 uint32* fragment_end) const { |
| 638 DCHECK(CalledOnValidThread()); | 627 DCHECK(CalledOnValidThread()); |
| 639 markup->clear(); | 628 markup->clear(); |
| 640 if (src_url) | 629 if (src_url) |
| 641 src_url->clear(); | 630 src_url->clear(); |
| 642 *fragment_start = 0; | 631 *fragment_start = 0; |
| 643 *fragment_end = 0; | 632 *fragment_end = 0; |
| 644 | 633 |
| 645 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 634 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 646 buffer, aurax11_details_->GetAtomsForFormat(GetHtmlFormatType()))); | 635 buffer, aurax11_details_->GetAtomsForFormat(GetHtmlFormatType()))); |
| 647 if (!data.get()) | 636 if (data.IsValid()) { |
| 648 return; | 637 *markup = data.GetHtml(); |
| 649 | 638 |
| 650 *markup = data->GetHtml(); | 639 *fragment_start = 0; |
| 651 | 640 DCHECK(markup->length() <= kuint32max); |
| 652 *fragment_start = 0; | 641 *fragment_end = static_cast<uint32>(markup->length()); |
| 653 DCHECK(markup->length() <= kuint32max); | 642 } |
| 654 *fragment_end = static_cast<uint32>(markup->length()); | |
| 655 } | 643 } |
| 656 | 644 |
| 657 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { | 645 void Clipboard::ReadRTF(Buffer buffer, std::string* result) const { |
| 658 DCHECK(CalledOnValidThread()); | 646 DCHECK(CalledOnValidThread()); |
| 659 | 647 |
| 660 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 648 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 661 buffer, aurax11_details_->GetAtomsForFormat(GetRtfFormatType()))); | 649 buffer, aurax11_details_->GetAtomsForFormat(GetRtfFormatType()))); |
| 662 if (data.get()) | 650 if (data.IsValid()) |
| 663 data->AssignTo(result); | 651 data.AssignTo(result); |
| 664 } | 652 } |
| 665 | 653 |
| 666 SkBitmap Clipboard::ReadImage(Buffer buffer) const { | 654 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |
| 667 DCHECK(CalledOnValidThread()); | 655 DCHECK(CalledOnValidThread()); |
| 668 NOTIMPLEMENTED(); | 656 NOTIMPLEMENTED(); |
| 669 return SkBitmap(); | 657 return SkBitmap(); |
| 670 } | 658 } |
| 671 | 659 |
| 672 void Clipboard::ReadCustomData(Buffer buffer, | 660 void Clipboard::ReadCustomData(Buffer buffer, |
| 673 const string16& type, | 661 const string16& type, |
| 674 string16* result) const { | 662 string16* result) const { |
| 675 DCHECK(CalledOnValidThread()); | 663 DCHECK(CalledOnValidThread()); |
| 676 | 664 |
| 677 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 665 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 678 buffer, | 666 buffer, |
| 679 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); | 667 aurax11_details_->GetAtomsForFormat(GetWebCustomDataFormatType()))); |
| 680 if (!data.get()) | 668 if (data.IsValid()) |
| 681 return; | 669 ReadCustomDataForType(data.GetData(), data.GetSize(), type, result); |
| 682 | |
| 683 ReadCustomDataForType(data->data(), data->size(), type, result); | |
| 684 } | 670 } |
| 685 | 671 |
| 686 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 672 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 687 DCHECK(CalledOnValidThread()); | 673 DCHECK(CalledOnValidThread()); |
| 688 // TODO(erg): This was left NOTIMPLEMENTED() in the gtk port too. | 674 // TODO(erg): This was left NOTIMPLEMENTED() in the gtk port too. |
| 689 NOTIMPLEMENTED(); | 675 NOTIMPLEMENTED(); |
| 690 } | 676 } |
| 691 | 677 |
| 692 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 678 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |
| 693 DCHECK(CalledOnValidThread()); | 679 DCHECK(CalledOnValidThread()); |
| 694 | 680 |
| 695 scoped_ptr<SelectionData> data(aurax11_details_->RequestAndWaitForTypes( | 681 SelectionData data(aurax11_details_->RequestAndWaitForTypes( |
| 696 BUFFER_STANDARD, aurax11_details_->GetAtomsForFormat(format))); | 682 BUFFER_STANDARD, aurax11_details_->GetAtomsForFormat(format))); |
| 697 if (data.get()) | 683 if (data.IsValid()) |
| 698 data->AssignTo(result); | 684 data.AssignTo(result); |
| 699 } | 685 } |
| 700 | 686 |
| 701 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 687 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
| 702 DCHECK(CalledOnValidThread()); | 688 DCHECK(CalledOnValidThread()); |
| 703 if (buffer == BUFFER_STANDARD) | 689 if (buffer == BUFFER_STANDARD) |
| 704 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); | 690 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); |
| 705 else | 691 else |
| 706 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); | 692 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); |
| 707 } | 693 } |
| 708 | 694 |
| 709 void Clipboard::WriteText(const char* text_data, size_t text_len) { | 695 void Clipboard::WriteText(const char* text_data, size_t text_len) { |
| 710 char* data = new char[text_len]; | 696 std::string str(text_data, text_len); |
| 711 memcpy(data, text_data, text_len); | 697 scoped_refptr<base::RefCountedMemory> mem( |
| 698 base::RefCountedString::TakeString(&str)); |
| 712 | 699 |
| 713 aurax11_details_->InsertMapping(kMimeTypeText, data, text_len); | 700 aurax11_details_->InsertMapping(kMimeTypeText, mem); |
| 714 aurax11_details_->InsertMapping(kText, data, text_len); | 701 aurax11_details_->InsertMapping(kText, mem); |
| 715 aurax11_details_->InsertMapping(kString, data, text_len); | 702 aurax11_details_->InsertMapping(kString, mem); |
| 716 aurax11_details_->InsertMapping(kUtf8String, data, text_len); | 703 aurax11_details_->InsertMapping(kUtf8String, mem); |
| 717 } | 704 } |
| 718 | 705 |
| 719 void Clipboard::WriteHTML(const char* markup_data, | 706 void Clipboard::WriteHTML(const char* markup_data, |
| 720 size_t markup_len, | 707 size_t markup_len, |
| 721 const char* url_data, | 708 const char* url_data, |
| 722 size_t url_len) { | 709 size_t url_len) { |
| 723 // TODO(estade): We need to expand relative links with |url_data|. | 710 // TODO(estade): We need to expand relative links with |url_data|. |
| 724 static const char* html_prefix = "<meta http-equiv=\"content-type\" " | 711 static const char* html_prefix = "<meta http-equiv=\"content-type\" " |
| 725 "content=\"text/html; charset=utf-8\">"; | 712 "content=\"text/html; charset=utf-8\">"; |
| 726 size_t html_prefix_len = strlen(html_prefix); | 713 std::string data = html_prefix; |
| 727 size_t total_len = html_prefix_len + markup_len + 1; | 714 data += std::string(markup_data, markup_len); |
| 715 // Some programs expect NULL-terminated data. See http://crbug.com/42624 |
| 716 data += '\0'; |
| 728 | 717 |
| 729 char* data = new char[total_len]; | 718 scoped_refptr<base::RefCountedMemory> mem( |
| 730 snprintf(data, total_len, "%s", html_prefix); | 719 base::RefCountedString::TakeString(&data)); |
| 731 memcpy(data + html_prefix_len, markup_data, markup_len); | 720 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 } | 721 } |
| 737 | 722 |
| 738 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { | 723 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { |
| 739 WriteData(GetRtfFormatType(), rtf_data, data_len); | 724 WriteData(GetRtfFormatType(), rtf_data, data_len); |
| 740 } | 725 } |
| 741 | 726 |
| 742 void Clipboard::WriteBookmark(const char* title_data, | 727 void Clipboard::WriteBookmark(const char* title_data, |
| 743 size_t title_len, | 728 size_t title_len, |
| 744 const char* url_data, | 729 const char* url_data, |
| 745 size_t url_len) { | 730 size_t url_len) { |
| 746 // Write as a mozilla url (UTF16: URL, newline, title). | 731 // Write as a mozilla url (UTF16: URL, newline, title). |
| 747 string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); | 732 string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); |
| 748 string16 title = UTF8ToUTF16(std::string(title_data, title_len)); | 733 string16 title = UTF8ToUTF16(std::string(title_data, title_len)); |
| 749 int data_len = 2 * (title.length() + url.length()); | |
| 750 | 734 |
| 751 char* data = new char[data_len]; | 735 std::vector<unsigned char> data; |
| 752 memcpy(data, url.data(), 2 * url.length()); | 736 ui::AddString16ToVector(url, &data); |
| 753 memcpy(data + 2 * url.length(), title.data(), 2 * title.length()); | 737 ui::AddString16ToVector(title, &data); |
| 754 aurax11_details_->InsertMapping(kMimeTypeMozillaURL, data, data_len); | 738 scoped_refptr<base::RefCountedMemory> mem( |
| 739 base::RefCountedBytes::TakeVector(&data)); |
| 740 |
| 741 aurax11_details_->InsertMapping(kMimeTypeMozillaURL, mem); |
| 755 } | 742 } |
| 756 | 743 |
| 757 // Write an extra flavor that signifies WebKit was the last to modify the | 744 // Write an extra flavor that signifies WebKit was the last to modify the |
| 758 // pasteboard. This flavor has no data. | 745 // pasteboard. This flavor has no data. |
| 759 void Clipboard::WriteWebSmartPaste() { | 746 void Clipboard::WriteWebSmartPaste() { |
| 760 aurax11_details_->InsertMapping(kMimeTypeWebkitSmartPaste, NULL, 0); | 747 aurax11_details_->InsertMapping(kMimeTypeWebkitSmartPaste, |
| 748 scoped_refptr<base::RefCountedMemory>()); |
| 761 } | 749 } |
| 762 | 750 |
| 763 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { | 751 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 | 752 // 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 | 753 // not. It's what the GTK port does, but I'm not sure it's the right thing to |
| 766 // do. | 754 // do. |
| 767 NOTIMPLEMENTED(); | 755 NOTIMPLEMENTED(); |
| 768 } | 756 } |
| 769 | 757 |
| 770 void Clipboard::WriteData(const FormatType& format, | 758 void Clipboard::WriteData(const FormatType& format, |
| 771 const char* data_data, | 759 const char* data_data, |
| 772 size_t data_len) { | 760 size_t data_len) { |
| 773 // We assume that certain mapping types are only written by trusted code. | 761 // We assume that certain mapping types are only written by trusted code. |
| 774 // Therefore we must upkeep their integrity. | 762 // Therefore we must upkeep their integrity. |
| 775 if (format.Equals(GetBitmapFormatType())) | 763 if (format.Equals(GetBitmapFormatType())) |
| 776 return; | 764 return; |
| 777 char* data = new char[data_len]; | 765 |
| 778 memcpy(data, data_data, data_len); | 766 std::vector<unsigned char> bytes(data_data, data_data + data_len); |
| 779 aurax11_details_->InsertMapping(format.ToString(), data, data_len); | 767 scoped_refptr<base::RefCountedMemory> mem( |
| 768 base::RefCountedBytes::TakeVector(&bytes)); |
| 769 aurax11_details_->InsertMapping(format.ToString(), mem); |
| 780 } | 770 } |
| 781 | 771 |
| 782 // static | 772 // static |
| 783 Clipboard::FormatType Clipboard::GetFormatType( | 773 Clipboard::FormatType Clipboard::GetFormatType( |
| 784 const std::string& format_string) { | 774 const std::string& format_string) { |
| 785 return FormatType::Deserialize(format_string); | 775 return FormatType::Deserialize(format_string); |
| 786 } | 776 } |
| 787 | 777 |
| 788 // static | 778 // static |
| 789 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { | 779 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 return type; | 838 return type; |
| 849 } | 839 } |
| 850 | 840 |
| 851 // static | 841 // static |
| 852 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { | 842 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { |
| 853 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); | 843 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData)); |
| 854 return type; | 844 return type; |
| 855 } | 845 } |
| 856 | 846 |
| 857 } // namespace ui | 847 } // namespace ui |
| OLD | NEW |