| 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(const ObjectMap& objects) { | 223 void Clipboard::WriteObjects(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(); | 232 SetGtkClipboard(); |
| 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() { | 245 void Clipboard::SetGtkClipboard() { |
| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 memcpy(data, data_data, data_len); | 344 memcpy(data, data_data, data_len); |
| 341 // TODO(dcheng): Maybe this map should use GdkAtoms... | 345 // TODO(dcheng): Maybe this map should use GdkAtoms... |
| 342 InsertMapping(GdkAtomToString(format.ToGdkAtom()).c_str(), data, data_len); | 346 InsertMapping(GdkAtomToString(format.ToGdkAtom()).c_str(), data, data_len); |
| 343 } | 347 } |
| 344 | 348 |
| 345 // We do not use gtk_clipboard_wait_is_target_available because of | 349 // We do not use gtk_clipboard_wait_is_target_available because of |
| 346 // a bug with the gtk clipboard. It caches the available targets | 350 // a bug with the gtk clipboard. It caches the available targets |
| 347 // and does not always refresh the cache when it is appropriate. | 351 // and does not always refresh the cache when it is appropriate. |
| 348 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, | 352 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, |
| 349 Clipboard::Buffer buffer) const { | 353 Clipboard::Buffer buffer) const { |
| 354 DCHECK(CalledOnValidThread()); |
| 350 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 355 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 351 if (clipboard == NULL) | 356 if (clipboard == NULL) |
| 352 return false; | 357 return false; |
| 353 | 358 |
| 354 bool retval = false; | 359 bool retval = false; |
| 355 GtkSelectionData* data = gtk_clipboard_wait_for_contents( | 360 GtkSelectionData* data = gtk_clipboard_wait_for_contents( |
| 356 clipboard, gdk_atom_intern_static_string("TARGETS")); | 361 clipboard, gdk_atom_intern_static_string("TARGETS")); |
| 357 | 362 |
| 358 bool format_is_plain_text = GetPlainTextFormatType().Equals(format); | 363 bool format_is_plain_text = GetPlainTextFormatType().Equals(format); |
| 359 if (format_is_plain_text) { | 364 if (format_is_plain_text) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 389 | 394 |
| 390 if (data) | 395 if (data) |
| 391 gtk_selection_data_free(data); | 396 gtk_selection_data_free(data); |
| 392 | 397 |
| 393 return retval; | 398 return retval; |
| 394 } | 399 } |
| 395 | 400 |
| 396 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, | 401 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, |
| 397 std::vector<string16>* types, | 402 std::vector<string16>* types, |
| 398 bool* contains_filenames) const { | 403 bool* contains_filenames) const { |
| 404 DCHECK(CalledOnValidThread()); |
| 399 if (!types || !contains_filenames) { | 405 if (!types || !contains_filenames) { |
| 400 NOTREACHED(); | 406 NOTREACHED(); |
| 401 return; | 407 return; |
| 402 } | 408 } |
| 403 | 409 |
| 404 types->clear(); | 410 types->clear(); |
| 405 if (IsFormatAvailable(GetPlainTextFormatType(), buffer)) | 411 if (IsFormatAvailable(GetPlainTextFormatType(), buffer)) |
| 406 types->push_back(UTF8ToUTF16(kMimeTypeText)); | 412 types->push_back(UTF8ToUTF16(kMimeTypeText)); |
| 407 if (IsFormatAvailable(GetHtmlFormatType(), buffer)) | 413 if (IsFormatAvailable(GetHtmlFormatType(), buffer)) |
| 408 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); | 414 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 419 if (!data) | 425 if (!data) |
| 420 return; | 426 return; |
| 421 ReadCustomDataTypes(gtk_selection_data_get_data(data), | 427 ReadCustomDataTypes(gtk_selection_data_get_data(data), |
| 422 gtk_selection_data_get_length(data), | 428 gtk_selection_data_get_length(data), |
| 423 types); | 429 types); |
| 424 gtk_selection_data_free(data); | 430 gtk_selection_data_free(data); |
| 425 } | 431 } |
| 426 | 432 |
| 427 | 433 |
| 428 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { | 434 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { |
| 435 DCHECK(CalledOnValidThread()); |
| 429 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 436 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 430 if (clipboard == NULL) | 437 if (clipboard == NULL) |
| 431 return; | 438 return; |
| 432 | 439 |
| 433 result->clear(); | 440 result->clear(); |
| 434 gchar* text = gtk_clipboard_wait_for_text(clipboard); | 441 gchar* text = gtk_clipboard_wait_for_text(clipboard); |
| 435 | 442 |
| 436 if (text == NULL) | 443 if (text == NULL) |
| 437 return; | 444 return; |
| 438 | 445 |
| 439 // TODO(estade): do we want to handle the possible error here? | 446 // TODO(estade): do we want to handle the possible error here? |
| 440 UTF8ToUTF16(text, strlen(text), result); | 447 UTF8ToUTF16(text, strlen(text), result); |
| 441 g_free(text); | 448 g_free(text); |
| 442 } | 449 } |
| 443 | 450 |
| 444 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, | 451 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, |
| 445 std::string* result) const { | 452 std::string* result) const { |
| 453 DCHECK(CalledOnValidThread()); |
| 446 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 454 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 447 if (clipboard == NULL) | 455 if (clipboard == NULL) |
| 448 return; | 456 return; |
| 449 | 457 |
| 450 result->clear(); | 458 result->clear(); |
| 451 gchar* text = gtk_clipboard_wait_for_text(clipboard); | 459 gchar* text = gtk_clipboard_wait_for_text(clipboard); |
| 452 | 460 |
| 453 if (text == NULL) | 461 if (text == NULL) |
| 454 return; | 462 return; |
| 455 | 463 |
| 456 result->assign(text); | 464 result->assign(text); |
| 457 g_free(text); | 465 g_free(text); |
| 458 } | 466 } |
| 459 | 467 |
| 460 void Clipboard::ReadFile(FilePath* file) const { | 468 void Clipboard::ReadFile(FilePath* file) const { |
| 469 DCHECK(CalledOnValidThread()); |
| 461 *file = FilePath(); | 470 *file = FilePath(); |
| 462 } | 471 } |
| 463 | 472 |
| 464 // TODO(estade): handle different charsets. | 473 // TODO(estade): handle different charsets. |
| 465 // TODO(port): set *src_url. | 474 // TODO(port): set *src_url. |
| 466 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, | 475 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, |
| 467 std::string* src_url, uint32* fragment_start, | 476 std::string* src_url, uint32* fragment_start, |
| 468 uint32* fragment_end) const { | 477 uint32* fragment_end) const { |
| 478 DCHECK(CalledOnValidThread()); |
| 469 markup->clear(); | 479 markup->clear(); |
| 470 if (src_url) | 480 if (src_url) |
| 471 src_url->clear(); | 481 src_url->clear(); |
| 472 *fragment_start = 0; | 482 *fragment_start = 0; |
| 473 *fragment_end = 0; | 483 *fragment_end = 0; |
| 474 | 484 |
| 475 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 485 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 476 if (clipboard == NULL) | 486 if (clipboard == NULL) |
| 477 return; | 487 return; |
| 478 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, | 488 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 499 markup->resize(markup->length() - 1); | 509 markup->resize(markup->length() - 1); |
| 500 | 510 |
| 501 *fragment_start = 0; | 511 *fragment_start = 0; |
| 502 DCHECK(markup->length() <= kuint32max); | 512 DCHECK(markup->length() <= kuint32max); |
| 503 *fragment_end = static_cast<uint32>(markup->length()); | 513 *fragment_end = static_cast<uint32>(markup->length()); |
| 504 | 514 |
| 505 gtk_selection_data_free(data); | 515 gtk_selection_data_free(data); |
| 506 } | 516 } |
| 507 | 517 |
| 508 SkBitmap Clipboard::ReadImage(Buffer buffer) const { | 518 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |
| 519 DCHECK(CalledOnValidThread()); |
| 509 ScopedGObject<GdkPixbuf>::Type pixbuf( | 520 ScopedGObject<GdkPixbuf>::Type pixbuf( |
| 510 gtk_clipboard_wait_for_image(clipboard_)); | 521 gtk_clipboard_wait_for_image(clipboard_)); |
| 511 if (!pixbuf.get()) | 522 if (!pixbuf.get()) |
| 512 return SkBitmap(); | 523 return SkBitmap(); |
| 513 | 524 |
| 514 gfx::CanvasSkia canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf.get()), | 525 gfx::CanvasSkia canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf.get()), |
| 515 gdk_pixbuf_get_height(pixbuf.get())), | 526 gdk_pixbuf_get_height(pixbuf.get())), |
| 516 false); | 527 false); |
| 517 { | 528 { |
| 518 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); | 529 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); |
| 519 cairo_t* context = scoped_platform_paint.GetPlatformSurface(); | 530 cairo_t* context = scoped_platform_paint.GetPlatformSurface(); |
| 520 gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0); | 531 gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0); |
| 521 cairo_paint(context); | 532 cairo_paint(context); |
| 522 } | 533 } |
| 523 return canvas.ExtractBitmap(); | 534 return canvas.ExtractBitmap(); |
| 524 } | 535 } |
| 525 | 536 |
| 526 void Clipboard::ReadCustomData(Buffer buffer, | 537 void Clipboard::ReadCustomData(Buffer buffer, |
| 527 const string16& type, | 538 const string16& type, |
| 528 string16* result) const { | 539 string16* result) const { |
| 540 DCHECK(CalledOnValidThread()); |
| 529 GtkClipboard* clipboard = LookupBackingClipboard(buffer); | 541 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 530 if (!clipboard) | 542 if (!clipboard) |
| 531 return; | 543 return; |
| 532 | 544 |
| 533 GtkSelectionData* data = gtk_clipboard_wait_for_contents( | 545 GtkSelectionData* data = gtk_clipboard_wait_for_contents( |
| 534 clipboard, GetWebCustomDataFormatType().ToGdkAtom()); | 546 clipboard, GetWebCustomDataFormatType().ToGdkAtom()); |
| 535 if (!data) | 547 if (!data) |
| 536 return; | 548 return; |
| 537 ReadCustomDataForType(gtk_selection_data_get_data(data), | 549 ReadCustomDataForType(gtk_selection_data_get_data(data), |
| 538 gtk_selection_data_get_length(data), | 550 gtk_selection_data_get_length(data), |
| 539 type, result); | 551 type, result); |
| 540 gtk_selection_data_free(data); | 552 gtk_selection_data_free(data); |
| 541 } | 553 } |
| 542 | 554 |
| 543 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 555 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 544 // TODO(estade): implement this. | 556 // TODO(estade): implement this. |
| 545 NOTIMPLEMENTED(); | 557 NOTIMPLEMENTED(); |
| 546 } | 558 } |
| 547 | 559 |
| 548 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 560 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |
| 561 DCHECK(CalledOnValidThread()); |
| 549 GtkSelectionData* data = | 562 GtkSelectionData* data = |
| 550 gtk_clipboard_wait_for_contents(clipboard_, format.ToGdkAtom()); | 563 gtk_clipboard_wait_for_contents(clipboard_, format.ToGdkAtom()); |
| 551 if (!data) | 564 if (!data) |
| 552 return; | 565 return; |
| 553 result->assign(reinterpret_cast<const char*>( | 566 result->assign(reinterpret_cast<const char*>( |
| 554 gtk_selection_data_get_data(data)), | 567 gtk_selection_data_get_data(data)), |
| 555 gtk_selection_data_get_length(data)); | 568 gtk_selection_data_get_length(data)); |
| 556 gtk_selection_data_free(data); | 569 gtk_selection_data_free(data); |
| 557 } | 570 } |
| 558 | 571 |
| 559 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 572 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
| 573 DCHECK(CalledOnValidThread()); |
| 560 if (buffer == BUFFER_STANDARD) | 574 if (buffer == BUFFER_STANDARD) |
| 561 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); | 575 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); |
| 562 else | 576 else |
| 563 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); | 577 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); |
| 564 } | 578 } |
| 565 | 579 |
| 566 //static | 580 //static |
| 567 Clipboard::FormatType Clipboard::GetFormatType( | 581 Clipboard::FormatType Clipboard::GetFormatType( |
| 568 const std::string& format_string) { | 582 const std::string& format_string) { |
| 569 return FormatType::Deserialize(format_string); | 583 return FormatType::Deserialize(format_string); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 return clipboard_; | 632 return clipboard_; |
| 619 case BUFFER_SELECTION: | 633 case BUFFER_SELECTION: |
| 620 return primary_selection_; | 634 return primary_selection_; |
| 621 default: | 635 default: |
| 622 NOTREACHED(); | 636 NOTREACHED(); |
| 623 return NULL; | 637 return NULL; |
| 624 } | 638 } |
| 625 } | 639 } |
| 626 | 640 |
| 627 } // namespace ui | 641 } // namespace ui |
| OLD | NEW |