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

Side by Side Diff: ui/base/clipboard/clipboard_gtk.cc

Issue 8801038: Make Clipboard::FormatType an opaque handle type. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix Linux build too? Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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>
11 #include <set> 11 #include <set>
12 #include <string> 12 #include <string>
13 #include <utility> 13 #include <utility>
14 14
15 #include "base/basictypes.h"
15 #include "base/file_path.h" 16 #include "base/file_path.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/memory/singleton.h" 18 #include "base/memory/singleton.h"
18 #include "base/utf_string_conversions.h" 19 #include "base/utf_string_conversions.h"
19 #include "third_party/skia/include/core/SkBitmap.h" 20 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "ui/base/clipboard/custom_data_helper.h" 21 #include "ui/base/clipboard/custom_data_helper.h"
21 #include "ui/base/gtk/gtk_signal.h" 22 #include "ui/base/gtk/gtk_signal.h"
22 #include "ui/base/x/x11_util.h" 23 #include "ui/base/x/x11_util.h"
23 #include "ui/gfx/canvas_skia.h" 24 #include "ui/gfx/canvas_skia.h"
24 #include "ui/gfx/gtk_util.h" 25 #include "ui/gfx/gtk_util.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 delete map; 174 delete map;
174 } 175 }
175 176
176 // Called on GdkPixbuf destruction; see WriteBitmap(). 177 // Called on GdkPixbuf destruction; see WriteBitmap().
177 void GdkPixbufFree(guchar* pixels, gpointer data) { 178 void GdkPixbufFree(guchar* pixels, gpointer data) {
178 free(pixels); 179 free(pixels);
179 } 180 }
180 181
181 } // namespace 182 } // namespace
182 183
184 Clipboard::FormatType::FormatType() {
185 }
186
187 Clipboard::FormatType::FormatType(const std::string& format_string)
188 : data_(StringToGdkAtom(format_string)) {
189 }
190
191 Clipboard::FormatType::FormatType(const GdkAtom& native_format)
192 : data_(native_format) {
193 }
194
195 Clipboard::FormatType::~FormatType() {
196 }
197
183 Clipboard::Clipboard() : clipboard_data_(NULL) { 198 Clipboard::Clipboard() : clipboard_data_(NULL) {
184 #if !defined(USE_AURA)
185 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); 199 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
186 primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); 200 primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
187 #endif
188 } 201 }
189 202
190 Clipboard::~Clipboard() { 203 Clipboard::~Clipboard() {
191 gtk_clipboard_store(clipboard_); 204 gtk_clipboard_store(clipboard_);
192 } 205 }
193 206
194 void Clipboard::WriteObjects(const ObjectMap& objects) { 207 void Clipboard::WriteObjects(const ObjectMap& objects) {
195 clipboard_data_ = new TargetMap(); 208 clipboard_data_ = new TargetMap();
196 209
197 for (ObjectMap::const_iterator iter = objects.begin(); 210 for (ObjectMap::const_iterator iter = objects.begin();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n"); 308 string16 url = UTF8ToUTF16(std::string(url_data, url_len) + "\n");
296 string16 title = UTF8ToUTF16(std::string(title_data, title_len)); 309 string16 title = UTF8ToUTF16(std::string(title_data, title_len));
297 int data_len = 2 * (title.length() + url.length()); 310 int data_len = 2 * (title.length() + url.length());
298 311
299 char* data = new char[data_len]; 312 char* data = new char[data_len];
300 memcpy(data, url.data(), 2 * url.length()); 313 memcpy(data, url.data(), 2 * url.length());
301 memcpy(data + 2 * url.length(), title.data(), 2 * title.length()); 314 memcpy(data + 2 * url.length(), title.data(), 2 * title.length());
302 InsertMapping(kMimeTypeMozillaURL, data, data_len); 315 InsertMapping(kMimeTypeMozillaURL, data, data_len);
303 } 316 }
304 317
305 void Clipboard::WriteData(const char* format_name, size_t format_len, 318 void Clipboard::WriteData(const FormatType& format,
306 const char* data_data, size_t data_len) { 319 const char* data_data,
307 std::string format(format_name, format_len); 320 size_t data_len) {
308 // We assume that certain mapping types are only written by trusted code. 321 // We assume that certain mapping types are only written by trusted code.
309 // Therefore we must upkeep their integrity. 322 // Therefore we must upkeep their integrity.
310 if (format == kMimeTypeBitmap) 323 if (format.data() == GetBitmapFormatType().data())
311 return; 324 return;
312 char* data = new char[data_len]; 325 char* data = new char[data_len];
313 memcpy(data, data_data, data_len); 326 memcpy(data, data_data, data_len);
314 InsertMapping(format.c_str(), data, data_len); 327 InsertMapping(GdkAtomToString(format.data()).c_str(), data, data_len);
315 } 328 }
316 329
317 // We do not use gtk_clipboard_wait_is_target_available because of 330 // We do not use gtk_clipboard_wait_is_target_available because of
318 // a bug with the gtk clipboard. It caches the available targets 331 // a bug with the gtk clipboard. It caches the available targets
319 // and does not always refresh the cache when it is appropriate. 332 // and does not always refresh the cache when it is appropriate.
320 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, 333 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format,
321 Clipboard::Buffer buffer) const { 334 Clipboard::Buffer buffer) const {
322 GtkClipboard* clipboard = LookupBackingClipboard(buffer); 335 GtkClipboard* clipboard = LookupBackingClipboard(buffer);
323 if (clipboard == NULL) 336 if (clipboard == NULL)
324 return false; 337 return false;
325 338
326 bool format_is_plain_text = GetPlainTextFormatType() == format; 339 bool format_is_plain_text =
340 GetPlainTextFormatType().data() == format.data();
327 if (format_is_plain_text) { 341 if (format_is_plain_text) {
328 // This tries a number of common text targets. 342 // This tries a number of common text targets.
329 if (gtk_clipboard_wait_is_text_available(clipboard)) 343 if (gtk_clipboard_wait_is_text_available(clipboard))
330 return true; 344 return true;
331 } 345 }
332 346
333 bool retval = false; 347 bool retval = false;
334 GdkAtom* targets = NULL; 348 GdkAtom* targets = NULL;
335 GtkSelectionData* data = 349 GtkSelectionData* data =
336 gtk_clipboard_wait_for_contents(clipboard, 350 gtk_clipboard_wait_for_contents(clipboard,
(...skipping 13 matching lines...) Expand all
350 if (num <= 0) { 364 if (num <= 0) {
351 if (format_is_plain_text) { 365 if (format_is_plain_text) {
352 gchar* text = gtk_clipboard_wait_for_text(clipboard); 366 gchar* text = gtk_clipboard_wait_for_text(clipboard);
353 if (text) { 367 if (text) {
354 g_free(text); 368 g_free(text);
355 retval = true; 369 retval = true;
356 } 370 }
357 } 371 }
358 } 372 }
359 373
360 GdkAtom format_atom = StringToGdkAtom(format);
361
362 for (int i = 0; i < num; i++) { 374 for (int i = 0; i < num; i++) {
363 if (targets[i] == format_atom) { 375 if (targets[i] == format.data()) {
364 retval = true; 376 retval = true;
365 break; 377 break;
366 } 378 }
367 } 379 }
368 380
369 g_free(targets); 381 g_free(targets);
370 gtk_selection_data_free(data); 382 gtk_selection_data_free(data);
371 383
372 return retval; 384 return retval;
373 } 385 }
374 386
375 bool Clipboard::IsFormatAvailableByString(const std::string& format,
376 Clipboard::Buffer buffer) const {
377 return IsFormatAvailable(format, buffer);
378 }
379
380 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, 387 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer,
381 std::vector<string16>* types, 388 std::vector<string16>* types,
382 bool* contains_filenames) const { 389 bool* contains_filenames) const {
383 if (!types || !contains_filenames) { 390 if (!types || !contains_filenames) {
384 NOTREACHED(); 391 NOTREACHED();
385 return; 392 return;
386 } 393 }
387 394
388 types->clear(); 395 types->clear();
389 if (IsFormatAvailable(GetPlainTextFormatType(), buffer)) 396 if (IsFormatAvailable(GetPlainTextFormatType(), buffer))
390 types->push_back(UTF8ToUTF16(kMimeTypeText)); 397 types->push_back(UTF8ToUTF16(kMimeTypeText));
391 if (IsFormatAvailable(GetHtmlFormatType(), buffer)) 398 if (IsFormatAvailable(GetHtmlFormatType(), buffer))
392 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); 399 types->push_back(UTF8ToUTF16(kMimeTypeHTML));
393 if (IsFormatAvailable(GetBitmapFormatType(), buffer)) 400 if (IsFormatAvailable(GetBitmapFormatType(), buffer))
394 types->push_back(UTF8ToUTF16(kMimeTypePNG)); 401 types->push_back(UTF8ToUTF16(kMimeTypePNG));
395 *contains_filenames = false; 402 *contains_filenames = false;
396 403
397 GtkClipboard* clipboard = LookupBackingClipboard(buffer); 404 GtkClipboard* clipboard = LookupBackingClipboard(buffer);
398 if (!clipboard) 405 if (!clipboard)
399 return; 406 return;
400 407
401 GtkSelectionData* data = gtk_clipboard_wait_for_contents( 408 GtkSelectionData* data = gtk_clipboard_wait_for_contents(
402 clipboard, StringToGdkAtom(GetWebCustomDataFormatType())); 409 clipboard, GetWebCustomDataFormatType().data());
403 if (!data) 410 if (!data)
404 return; 411 return;
405 ReadCustomDataTypes(data->data, data->length, types); 412 ReadCustomDataTypes(data->data, data->length, types);
406 gtk_selection_data_free(data); 413 gtk_selection_data_free(data);
407 } 414 }
408 415
409 416
410 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { 417 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const {
411 GtkClipboard* clipboard = LookupBackingClipboard(buffer); 418 GtkClipboard* clipboard = LookupBackingClipboard(buffer);
412 if (clipboard == NULL) 419 if (clipboard == NULL)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 markup->clear(); 458 markup->clear();
452 if (src_url) 459 if (src_url)
453 src_url->clear(); 460 src_url->clear();
454 *fragment_start = 0; 461 *fragment_start = 0;
455 *fragment_end = 0; 462 *fragment_end = 0;
456 463
457 GtkClipboard* clipboard = LookupBackingClipboard(buffer); 464 GtkClipboard* clipboard = LookupBackingClipboard(buffer);
458 if (clipboard == NULL) 465 if (clipboard == NULL)
459 return; 466 return;
460 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, 467 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard,
461 StringToGdkAtom(GetHtmlFormatType())); 468 GetHtmlFormatType().data());
462 469
463 if (!data) 470 if (!data)
464 return; 471 return;
465 472
466 // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is 473 // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is
467 // UTF-16, otherwise assume UTF-8. 474 // UTF-16, otherwise assume UTF-8.
468 if (data->length >= 2 && 475 if (data->length >= 2 &&
469 reinterpret_cast<uint16_t*>(data->data)[0] == 0xFEFF) { 476 reinterpret_cast<uint16_t*>(data->data)[0] == 0xFEFF) {
470 markup->assign(reinterpret_cast<uint16_t*>(data->data) + 1, 477 markup->assign(reinterpret_cast<uint16_t*>(data->data) + 1,
471 (data->length / 2) - 1); 478 (data->length / 2) - 1);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 } 510 }
504 511
505 void Clipboard::ReadCustomData(Buffer buffer, 512 void Clipboard::ReadCustomData(Buffer buffer,
506 const string16& type, 513 const string16& type,
507 string16* result) const { 514 string16* result) const {
508 GtkClipboard* clipboard = LookupBackingClipboard(buffer); 515 GtkClipboard* clipboard = LookupBackingClipboard(buffer);
509 if (!clipboard) 516 if (!clipboard)
510 return; 517 return;
511 518
512 GtkSelectionData* data = gtk_clipboard_wait_for_contents( 519 GtkSelectionData* data = gtk_clipboard_wait_for_contents(
513 clipboard, StringToGdkAtom(GetWebCustomDataFormatType())); 520 clipboard, GetWebCustomDataFormatType().data());
514 if (!data) 521 if (!data)
515 return; 522 return;
516 ReadCustomDataForType(data->data, data->length, type, result); 523 ReadCustomDataForType(data->data, data->length, type, result);
517 gtk_selection_data_free(data); 524 gtk_selection_data_free(data);
518 } 525 }
519 526
520 void Clipboard::ReadBookmark(string16* title, std::string* url) const { 527 void Clipboard::ReadBookmark(string16* title, std::string* url) const {
521 // TODO(estade): implement this. 528 // TODO(estade): implement this.
522 NOTIMPLEMENTED(); 529 NOTIMPLEMENTED();
523 } 530 }
524 531
525 void Clipboard::ReadData(const std::string& format, std::string* result) const { 532 void Clipboard::ReadData(const FormatType& format, std::string* result) const {
526 GtkSelectionData* data = 533 GtkSelectionData* data =
527 gtk_clipboard_wait_for_contents(clipboard_, StringToGdkAtom(format)); 534 gtk_clipboard_wait_for_contents(clipboard_, format.data());
528 if (!data) 535 if (!data)
529 return; 536 return;
530 result->assign(reinterpret_cast<char*>(data->data), data->length); 537 result->assign(reinterpret_cast<char*>(data->data), data->length);
531 gtk_selection_data_free(data); 538 gtk_selection_data_free(data);
532 } 539 }
533 540
534 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { 541 uint64 Clipboard::GetSequenceNumber(Buffer buffer) {
535 if (buffer == BUFFER_STANDARD) 542 if (buffer == BUFFER_STANDARD)
536 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number(); 543 return SelectionChangeObserver::GetInstance()->clipboard_sequence_number();
537 else 544 else
538 return SelectionChangeObserver::GetInstance()->primary_sequence_number(); 545 return SelectionChangeObserver::GetInstance()->primary_sequence_number();
539 } 546 }
540 547
541 // static 548 //static
542 Clipboard::FormatType Clipboard::GetPlainTextFormatType() { 549 Clipboard::FormatType Clipboard::RegisterFormatType(
543 return GdkAtomToString(GDK_TARGET_STRING); 550 const std::string& format_string) {
551 return StringToFormatType(format_string);
544 } 552 }
545 553
546 // static 554 // static
547 Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { 555 std::string Clipboard::FormatTypeToString(const FormatType& type) {
556 return GdkAtomToString(type.data());
557 }
558
559 // static
560 Clipboard::FormatType Clipboard::StringToFormatType(
561 const std::string& format_string) {
562 return FormatType(StringToGdkAtom(format_string));
563 }
564
565 // static
566 const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() {
567 CR_DEFINE_STATIC_LOCAL(
568 FormatType, type, (GDK_TARGET_STRING));
569 return type;
570 }
571
572 // static
573 const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() {
548 return GetPlainTextFormatType(); 574 return GetPlainTextFormatType();
549 } 575 }
550 576
551 // static 577 // static
552 Clipboard::FormatType Clipboard::GetHtmlFormatType() { 578 const Clipboard::FormatType& Clipboard::GetHtmlFormatType() {
553 return std::string(kMimeTypeHTML); 579 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeHTML));
580 return type;
554 } 581 }
555 582
556 // static 583 // static
557 Clipboard::FormatType Clipboard::GetBitmapFormatType() { 584 const Clipboard::FormatType& Clipboard::GetBitmapFormatType() {
558 return std::string(kMimeTypeBitmap); 585 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeBitmap));
586 return type;
559 } 587 }
560 588
561 // static 589 // static
562 Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { 590 const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() {
563 return std::string(kMimeTypeWebkitSmartPaste); 591 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebkitSmartPaste));
592 return type;
564 } 593 }
565 594
566 // static 595 // static
567 Clipboard::FormatType Clipboard::GetWebCustomDataFormatType() { 596 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() {
568 return std::string(kMimeTypeWebCustomData); 597 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData));
598 return type;
569 } 599 }
570 600
571 void Clipboard::InsertMapping(const char* key, 601 void Clipboard::InsertMapping(const char* key,
572 char* data, 602 char* data,
573 size_t data_len) { 603 size_t data_len) {
574 DCHECK(clipboard_data_->find(key) == clipboard_data_->end()); 604 DCHECK(clipboard_data_->find(key) == clipboard_data_->end());
575 (*clipboard_data_)[key] = std::make_pair(data, data_len); 605 (*clipboard_data_)[key] = std::make_pair(data, data_len);
576 } 606 }
577 607
578 GtkClipboard* Clipboard::LookupBackingClipboard(Buffer clipboard) const { 608 GtkClipboard* Clipboard::LookupBackingClipboard(Buffer clipboard) const {
579 switch (clipboard) { 609 switch (clipboard) {
580 case BUFFER_STANDARD: 610 case BUFFER_STANDARD:
581 return clipboard_; 611 return clipboard_;
582 case BUFFER_SELECTION: 612 case BUFFER_SELECTION:
583 return primary_selection_; 613 return primary_selection_;
584 default: 614 default:
585 NOTREACHED(); 615 NOTREACHED();
586 return NULL; 616 return NULL;
587 } 617 }
588 } 618 }
589 619
590 } // namespace ui 620 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698