| 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 <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 #include <X11/extensions/Xfixes.h> | 8 #include <X11/extensions/Xfixes.h> |
| 9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 Clipboard::FormatType Clipboard::FormatType::Deserialize( | 203 Clipboard::FormatType Clipboard::FormatType::Deserialize( |
| 204 const std::string& serialization) { | 204 const std::string& serialization) { |
| 205 return FormatType(serialization); | 205 return FormatType(serialization); |
| 206 } | 206 } |
| 207 | 207 |
| 208 bool Clipboard::FormatType::Equals(const FormatType& other) const { | 208 bool Clipboard::FormatType::Equals(const FormatType& other) const { |
| 209 return data_ == other.data_; | 209 return data_ == other.data_; |
| 210 } | 210 } |
| 211 | 211 |
| 212 Clipboard::Clipboard() : clipboard_data_(NULL) { | 212 Clipboard::Clipboard() : clipboard_data_(NULL) { |
| 213 DCHECK(CalledOnValidThread()); |
| 213 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); | 214 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); |
| 214 primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); | 215 primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
| 215 } | 216 } |
| 216 | 217 |
| 217 Clipboard::~Clipboard() { | 218 Clipboard::~Clipboard() { |
| 219 DCHECK(CalledOnValidThread()); |
| 218 gtk_clipboard_store(clipboard_); | 220 gtk_clipboard_store(clipboard_); |
| 219 } | 221 } |
| 220 | 222 |
| 221 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { | 223 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { |
| 224 DCHECK(CalledOnValidThread()); |
| 222 clipboard_data_ = new TargetMap(); | 225 clipboard_data_ = new TargetMap(); |
| 223 | 226 |
| 224 for (ObjectMap::const_iterator iter = objects.begin(); | 227 for (ObjectMap::const_iterator iter = objects.begin(); |
| 225 iter != objects.end(); ++iter) { | 228 iter != objects.end(); ++iter) { |
| 226 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | 229 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 227 } | 230 } |
| 228 | 231 |
| 229 SetGtkClipboard(buffer); | 232 SetGtkClipboard(buffer); |
| 230 } | 233 } |
| 231 | 234 |
| 232 // When a URL is copied from a render view context menu (via "copy link | 235 // When a URL is copied from a render view context menu (via "copy link |
| 233 // location", for example), we additionally stick it in the X clipboard. This | 236 // location", for example), we additionally stick it in the X clipboard. This |
| 234 // matches other linux browsers. | 237 // matches other linux browsers. |
| 235 void Clipboard::DidWriteURL(const std::string& utf8_text) { | 238 void Clipboard::DidWriteURL(const std::string& utf8_text) { |
| 239 DCHECK(CalledOnValidThread()); |
| 236 gtk_clipboard_set_text(primary_selection_, utf8_text.c_str(), | 240 gtk_clipboard_set_text(primary_selection_, utf8_text.c_str(), |
| 237 utf8_text.length()); | 241 utf8_text.length()); |
| 238 } | 242 } |
| 239 | 243 |
| 240 // Take ownership of the GTK clipboard and inform it of the targets we support. | 244 // Take ownership of the GTK clipboard and inform it of the targets we support. |
| 241 void Clipboard::SetGtkClipboard(Buffer buffer) { | 245 void Clipboard::SetGtkClipboard(Buffer buffer) { |
| 242 scoped_array<GtkTargetEntry> targets( | 246 scoped_array<GtkTargetEntry> targets( |
| 243 new GtkTargetEntry[clipboard_data_->size()]); | 247 new GtkTargetEntry[clipboard_data_->size()]); |
| 244 | 248 |
| 245 int i = 0; | 249 int i = 0; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 memcpy(data, data_data, data_len); | 346 memcpy(data, data_data, data_len); |
| 343 // TODO(dcheng): Maybe this map should use GdkAtoms... | 347 // TODO(dcheng): Maybe this map should use GdkAtoms... |
| 344 InsertMapping(GdkAtomToString(format.ToGdkAtom()).c_str(), data, data_len); | 348 InsertMapping(GdkAtomToString(format.ToGdkAtom()).c_str(), data, data_len); |
| 345 } | 349 } |
| 346 | 350 |
| 347 // We do not use gtk_clipboard_wait_is_target_available because of | 351 // We do not use gtk_clipboard_wait_is_target_available because of |
| 348 // a bug with the gtk clipboard. It caches the available targets | 352 // a bug with the gtk clipboard. It caches the available targets |
| 349 // and does not always refresh the cache when it is appropriate. | 353 // and does not always refresh the cache when it is appropriate. |
| 350 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, | 354 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, |
| 351 Clipboard::Buffer buffer) const { | 355 Clipboard::Buffer buffer) const { |
| 356 DCHECK(CalledOnValidThread()); |
| 352 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 357 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 353 if (clipboard == NULL) | 358 if (clipboard == NULL) |
| 354 return false; | 359 return false; |
| 355 | 360 |
| 356 bool retval = false; | 361 bool retval = false; |
| 357 GtkSelectionData* data = gtk_clipboard_wait_for_contents( | 362 GtkSelectionData* data = gtk_clipboard_wait_for_contents( |
| 358 clipboard, gdk_atom_intern_static_string("TARGETS")); | 363 clipboard, gdk_atom_intern_static_string("TARGETS")); |
| 359 | 364 |
| 360 bool format_is_plain_text = GetPlainTextFormatType().Equals(format); | 365 bool format_is_plain_text = GetPlainTextFormatType().Equals(format); |
| 361 if (format_is_plain_text) { | 366 if (format_is_plain_text) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 391 | 396 |
| 392 if (data) | 397 if (data) |
| 393 gtk_selection_data_free(data); | 398 gtk_selection_data_free(data); |
| 394 | 399 |
| 395 return retval; | 400 return retval; |
| 396 } | 401 } |
| 397 | 402 |
| 398 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, | 403 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, |
| 399 std::vector<string16>* types, | 404 std::vector<string16>* types, |
| 400 bool* contains_filenames) const { | 405 bool* contains_filenames) const { |
| 406 DCHECK(CalledOnValidThread()); |
| 401 if (!types || !contains_filenames) { | 407 if (!types || !contains_filenames) { |
| 402 NOTREACHED(); | 408 NOTREACHED(); |
| 403 return; | 409 return; |
| 404 } | 410 } |
| 405 | 411 |
| 406 types->clear(); | 412 types->clear(); |
| 407 if (IsFormatAvailable(GetPlainTextFormatType(), buffer)) | 413 if (IsFormatAvailable(GetPlainTextFormatType(), buffer)) |
| 408 types->push_back(UTF8ToUTF16(kMimeTypeText)); | 414 types->push_back(UTF8ToUTF16(kMimeTypeText)); |
| 409 if (IsFormatAvailable(GetHtmlFormatType(), buffer)) | 415 if (IsFormatAvailable(GetHtmlFormatType(), buffer)) |
| 410 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); | 416 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 421 if (!data) | 427 if (!data) |
| 422 return; | 428 return; |
| 423 ReadCustomDataTypes(gtk_selection_data_get_data(data), | 429 ReadCustomDataTypes(gtk_selection_data_get_data(data), |
| 424 gtk_selection_data_get_length(data), | 430 gtk_selection_data_get_length(data), |
| 425 types); | 431 types); |
| 426 gtk_selection_data_free(data); | 432 gtk_selection_data_free(data); |
| 427 } | 433 } |
| 428 | 434 |
| 429 | 435 |
| 430 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { | 436 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { |
| 437 DCHECK(CalledOnValidThread()); |
| 431 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 438 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 432 if (clipboard == NULL) | 439 if (clipboard == NULL) |
| 433 return; | 440 return; |
| 434 | 441 |
| 435 result->clear(); | 442 result->clear(); |
| 436 gchar* text = gtk_clipboard_wait_for_text(clipboard); | 443 gchar* text = gtk_clipboard_wait_for_text(clipboard); |
| 437 | 444 |
| 438 if (text == NULL) | 445 if (text == NULL) |
| 439 return; | 446 return; |
| 440 | 447 |
| 441 // TODO(estade): do we want to handle the possible error here? | 448 // TODO(estade): do we want to handle the possible error here? |
| 442 UTF8ToUTF16(text, strlen(text), result); | 449 UTF8ToUTF16(text, strlen(text), result); |
| 443 g_free(text); | 450 g_free(text); |
| 444 } | 451 } |
| 445 | 452 |
| 446 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, | 453 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, |
| 447 std::string* result) const { | 454 std::string* result) const { |
| 455 DCHECK(CalledOnValidThread()); |
| 448 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 456 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 449 if (clipboard == NULL) | 457 if (clipboard == NULL) |
| 450 return; | 458 return; |
| 451 | 459 |
| 452 result->clear(); | 460 result->clear(); |
| 453 gchar* text = gtk_clipboard_wait_for_text(clipboard); | 461 gchar* text = gtk_clipboard_wait_for_text(clipboard); |
| 454 | 462 |
| 455 if (text == NULL) | 463 if (text == NULL) |
| 456 return; | 464 return; |
| 457 | 465 |
| 458 result->assign(text); | 466 result->assign(text); |
| 459 g_free(text); | 467 g_free(text); |
| 460 } | 468 } |
| 461 | 469 |
| 462 // TODO(estade): handle different charsets. | 470 // TODO(estade): handle different charsets. |
| 463 // TODO(port): set *src_url. | 471 // TODO(port): set *src_url. |
| 464 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, | 472 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, |
| 465 std::string* src_url, uint32* fragment_start, | 473 std::string* src_url, uint32* fragment_start, |
| 466 uint32* fragment_end) const { | 474 uint32* fragment_end) const { |
| 475 DCHECK(CalledOnValidThread()); |
| 467 markup->clear(); | 476 markup->clear(); |
| 468 if (src_url) | 477 if (src_url) |
| 469 src_url->clear(); | 478 src_url->clear(); |
| 470 *fragment_start = 0; | 479 *fragment_start = 0; |
| 471 *fragment_end = 0; | 480 *fragment_end = 0; |
| 472 | 481 |
| 473 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 482 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 474 if (clipboard == NULL) | 483 if (clipboard == NULL) |
| 475 return; | 484 return; |
| 476 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, | 485 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 497 markup->resize(markup->length() - 1); | 506 markup->resize(markup->length() - 1); |
| 498 | 507 |
| 499 *fragment_start = 0; | 508 *fragment_start = 0; |
| 500 DCHECK(markup->length() <= kuint32max); | 509 DCHECK(markup->length() <= kuint32max); |
| 501 *fragment_end = static_cast<uint32>(markup->length()); | 510 *fragment_end = static_cast<uint32>(markup->length()); |
| 502 | 511 |
| 503 gtk_selection_data_free(data); | 512 gtk_selection_data_free(data); |
| 504 } | 513 } |
| 505 | 514 |
| 506 SkBitmap Clipboard::ReadImage(Buffer buffer) const { | 515 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |
| 516 DCHECK(CalledOnValidThread()); |
| 507 ScopedGObject<GdkPixbuf>::Type pixbuf( | 517 ScopedGObject<GdkPixbuf>::Type pixbuf( |
| 508 gtk_clipboard_wait_for_image(clipboard_)); | 518 gtk_clipboard_wait_for_image(clipboard_)); |
| 509 if (!pixbuf.get()) | 519 if (!pixbuf.get()) |
| 510 return SkBitmap(); | 520 return SkBitmap(); |
| 511 | 521 |
| 512 gfx::CanvasSkia canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf.get()), | 522 gfx::CanvasSkia canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf.get()), |
| 513 gdk_pixbuf_get_height(pixbuf.get())), | 523 gdk_pixbuf_get_height(pixbuf.get())), |
| 514 false); | 524 false); |
| 515 { | 525 { |
| 516 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); | 526 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); |
| 517 cairo_t* context = scoped_platform_paint.GetPlatformSurface(); | 527 cairo_t* context = scoped_platform_paint.GetPlatformSurface(); |
| 518 gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0); | 528 gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0); |
| 519 cairo_paint(context); | 529 cairo_paint(context); |
| 520 } | 530 } |
| 521 return canvas.ExtractBitmap(); | 531 return canvas.ExtractBitmap(); |
| 522 } | 532 } |
| 523 | 533 |
| 524 void Clipboard::ReadCustomData(Buffer buffer, | 534 void Clipboard::ReadCustomData(Buffer buffer, |
| 525 const string16& type, | 535 const string16& type, |
| 526 string16* result) const { | 536 string16* result) const { |
| 537 DCHECK(CalledOnValidThread()); |
| 527 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 538 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 528 if (!clipboard) | 539 if (!clipboard) |
| 529 return; | 540 return; |
| 530 | 541 |
| 531 GtkSelectionData* data = gtk_clipboard_wait_for_contents( | 542 GtkSelectionData* data = gtk_clipboard_wait_for_contents( |
| 532 clipboard, GetWebCustomDataFormatType().ToGdkAtom()); | 543 clipboard, GetWebCustomDataFormatType().ToGdkAtom()); |
| 533 if (!data) | 544 if (!data) |
| 534 return; | 545 return; |
| 535 ReadCustomDataForType(gtk_selection_data_get_data(data), | 546 ReadCustomDataForType(gtk_selection_data_get_data(data), |
| 536 gtk_selection_data_get_length(data), | 547 gtk_selection_data_get_length(data), |
| 537 type, result); | 548 type, result); |
| 538 gtk_selection_data_free(data); | 549 gtk_selection_data_free(data); |
| 539 } | 550 } |
| 540 | 551 |
| 541 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 552 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 542 // TODO(estade): implement this. | 553 // TODO(estade): implement this. |
| 543 NOTIMPLEMENTED(); | 554 NOTIMPLEMENTED(); |
| 544 } | 555 } |
| 545 | 556 |
| 546 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 557 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |
| 558 DCHECK(CalledOnValidThread()); |
| 547 GtkSelectionData* data = | 559 GtkSelectionData* data = |
| 548 gtk_clipboard_wait_for_contents(clipboard_, format.ToGdkAtom()); | 560 gtk_clipboard_wait_for_contents(clipboard_, format.ToGdkAtom()); |
| 549 if (!data) | 561 if (!data) |
| 550 return; | 562 return; |
| 551 result->assign(reinterpret_cast<const char*>( | 563 result->assign(reinterpret_cast<const char*>( |
| 552 gtk_selection_data_get_data(data)), | 564 gtk_selection_data_get_data(data)), |
| 553 gtk_selection_data_get_length(data)); | 565 gtk_selection_data_get_length(data)); |
| 554 gtk_selection_data_free(data); | 566 gtk_selection_data_free(data); |
| 555 } | 567 } |
| 556 | 568 |
| 557 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 569 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
| 570 DCHECK(CalledOnValidThread()); |
| 558 if (buffer == BUFFER_STANDARD) | 571 if (buffer == BUFFER_STANDARD) |
| 559 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); | 572 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); |
| 560 else | 573 else |
| 561 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); | 574 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); |
| 562 } | 575 } |
| 563 | 576 |
| 564 //static | 577 //static |
| 565 Clipboard::FormatType Clipboard::GetFormatType( | 578 Clipboard::FormatType Clipboard::GetFormatType( |
| 566 const std::string& format_string) { | 579 const std::string& format_string) { |
| 567 return FormatType::Deserialize(format_string); | 580 return FormatType::Deserialize(format_string); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 return clipboard_; | 629 return clipboard_; |
| 617 case BUFFER_SELECTION: | 630 case BUFFER_SELECTION: |
| 618 return primary_selection_; | 631 return primary_selection_; |
| 619 default: | 632 default: |
| 620 NOTREACHED(); | 633 NOTREACHED(); |
| 621 return NULL; | 634 return NULL; |
| 622 } | 635 } |
| 623 } | 636 } |
| 624 | 637 |
| 625 } // namespace ui | 638 } // namespace ui |
| OLD | NEW |