diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-17 19:22:22 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-17 19:22:22 +0000 |
commit | 2c8ef3436c78e91286f378bc8b50a3e6b0a86de7 (patch) | |
tree | cea3ba40c9a9293ce70c387bb292abe6e820dd06 | |
parent | 4fde25f4d28399b79fc209869ad8d98a20aa1b0e (diff) | |
download | chromium_src-2c8ef3436c78e91286f378bc8b50a3e6b0a86de7.zip chromium_src-2c8ef3436c78e91286f378bc8b50a3e6b0a86de7.tar.gz chromium_src-2c8ef3436c78e91286f378bc8b50a3e6b0a86de7.tar.bz2 |
Added linux clipboard.
Review URL: http://codereview.chromium.org/7602
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3548 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/SConscript | 3 | ||||
-rw-r--r-- | base/clipboard.h | 7 | ||||
-rw-r--r-- | base/clipboard_linux.cc | 160 | ||||
-rw-r--r-- | base/clipboard_unittest.cc | 10 | ||||
-rw-r--r-- | base/test_suite.h | 5 |
5 files changed, 179 insertions, 6 deletions
diff --git a/base/SConscript b/base/SConscript index 9b022c4..2d7e8a7 100644 --- a/base/SConscript +++ b/base/SConscript @@ -166,6 +166,7 @@ if env['PLATFORM'] == 'posix': input_files.extend([ 'atomicops_internals_x86_gcc.cc', 'base_paths_linux.cc', + 'clipboard_linux.cc', 'file_util_linux.cc', 'hmac_nss.cc', 'message_pump_glib.cc', @@ -253,6 +254,7 @@ if env['PLATFORM'] in ('posix', 'darwin'): test_files = [ 'at_exit_unittest.cc', 'atomicops_unittest.cc', + 'clipboard_unittest.cc', 'command_line_unittest.cc', 'condition_variable_unittest.cc', 'file_path_unittest.cc', @@ -305,7 +307,6 @@ if env['PLATFORM'] == 'win32': env_tests.ChromeTestProgram('debug_message', ['debug_message.cc']) test_files.extend([ - 'clipboard_unittest.cc', 'directory_watcher_unittest.cc', 'idletimer_unittest.cc', 'process_util_unittest.cc', diff --git a/base/clipboard.h b/base/clipboard.h index 03def67..f9f21b1 100644 --- a/base/clipboard.h +++ b/base/clipboard.h @@ -26,8 +26,9 @@ class Clipboard { typedef unsigned int FormatType; #elif defined(OS_MACOSX) typedef NSString *FormatType; -#else - typedef unsigned int FormatType; +#elif defined(OS_LINUX) + typedef struct _GdkAtom* FormatType; + typedef struct _GtkClipboard GtkClipboard; #endif Clipboard(); @@ -133,6 +134,8 @@ class Clipboard { std::string* url); HWND clipboard_owner_; +#elif defined(OS_LINUX) + GtkClipboard* clipboard_; #endif DISALLOW_EVIL_CONSTRUCTORS(Clipboard); diff --git a/base/clipboard_linux.cc b/base/clipboard_linux.cc new file mode 100644 index 0000000..af929c3f --- /dev/null +++ b/base/clipboard_linux.cc @@ -0,0 +1,160 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/clipboard.h" +#include "base/string_util.h" + +#include <gtk/gtk.h> +#include <string.h> + +namespace { + +static const char* kMimeHtml = "text/html"; + +void GetHtml(GtkClipboard* clipboard, + GtkSelectionData* selection_data, + guint info, + gpointer user_data) { + if (selection_data->target != gdk_atom_intern(kMimeHtml, false)) + return; + + gtk_selection_data_set(selection_data, gdk_atom_intern(kMimeHtml, false), + 8, + static_cast<guchar*>(user_data), + strlen(static_cast<char*>(user_data))); +} + +void ClearHtml(GtkClipboard* clipboard, + gpointer user_data) { + delete[] static_cast<char*>(user_data); +} + +void GetNoOp(GtkClipboard* clipboard, + GtkSelectionData* selection_data, + guint info, + gpointer user_data) { +} + +void ClearNoOp(GtkClipboard* clipboard, + gpointer user_data) { +} + +} + +Clipboard::Clipboard() { + clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); +} + +Clipboard::~Clipboard() { + // TODO(estade): enable this (must first use gtk_clipboard_set_can_store()?) + // gtk_clipboard_store(clipboard_); +} + +void Clipboard::Clear() { + // gtk_clipboard_clear() does not appear to be enough. We must first grab + // ownership of the clipboard by setting data. + GtkTargetEntry empty_target[] = {}; + gtk_clipboard_set_with_data(clipboard_, empty_target, 0, + GetNoOp, ClearNoOp, NULL); + gtk_clipboard_clear(clipboard_); +} + +void Clipboard::WriteText(const std::wstring& text) { + std::string utf8_text = WideToUTF8(text); + + gtk_clipboard_set_text(clipboard_, utf8_text.c_str(), utf8_text.size()); +} + +void Clipboard::WriteHTML(const std::wstring& markup, + const std::string& src_url) { + // TODO(estade): might not want to ignore src_url + std::string html = WideToUTF8(markup); + char* html_data = new char[html.size() + 1]; + strcpy(html_data, html.c_str()); + + char target_format[strlen(kMimeHtml) + 1]; + strcpy(target_format, kMimeHtml); + GtkTargetEntry target[] = { {target_format, 0} }; + + if (!gtk_clipboard_set_with_data(clipboard_, target, 1, + GetHtml, ClearHtml, html_data)) { + delete[] html_data; + } +} + +bool Clipboard::IsFormatAvailable(Clipboard::FormatType format) const { + if (format == GetPlainTextFormatType()) { + return gtk_clipboard_wait_is_text_available(clipboard_); + } + + return gtk_clipboard_wait_is_target_available(clipboard_, format); +} + +void Clipboard::ReadText(std::wstring* result) const { + if (!result) { + NOTREACHED(); + return; + } + + result->clear(); + gchar* text = gtk_clipboard_wait_for_text(clipboard_); + + if (text == NULL) + return; + + // TODO(estade): do we want to handle the possible error here? + UTF8ToWide(text, strlen(text), result); + g_free(text); +} + +void Clipboard::ReadAsciiText(std::string* result) const { + if (!result) { + NOTREACHED(); + return; + } + + result->clear(); + gchar* text = gtk_clipboard_wait_for_text(clipboard_); + + if (text == NULL) + return; + + result->assign(text); + g_free(text); +} + +void Clipboard::ReadHTML(std::wstring* markup, std::string* src_url) const { + if (!markup) { + NOTREACHED(); + return; + } + + markup->clear(); + + GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard_, + GetHtmlFormatType()); + + if (!data) + return; + + std::string html(reinterpret_cast<char*>(data->data)); + markup->assign(UTF8ToWide(html)); +} + +// static +Clipboard::FormatType Clipboard::GetPlainTextFormatType() { + return GDK_TARGET_STRING; +} + +// static +Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { + // all gtk clipboard strings are UTF8 + return GetPlainTextFormatType(); +} + +// static +Clipboard::FormatType Clipboard::GetHtmlFormatType() { + return gdk_atom_intern(kMimeHtml, false); +} + diff --git a/base/clipboard_unittest.cc b/base/clipboard_unittest.cc index 6e72c81..c035c9c0 100644 --- a/base/clipboard_unittest.cc +++ b/base/clipboard_unittest.cc @@ -16,6 +16,8 @@ TEST_F(ClipboardTest, ClearTest) { Clipboard clipboard; clipboard.Clear(); + clipboard.WriteText(L"erase me"); + clipboard.Clear(); EXPECT_EQ(false, clipboard.IsFormatAvailable( Clipboard::GetPlainTextFormatType())); EXPECT_EQ(false, clipboard.IsFormatAvailable( @@ -52,14 +54,15 @@ TEST_F(ClipboardTest, HTMLTest) { Clipboard::GetHtmlFormatType())); clipboard.ReadHTML(&markup_result, &url_result); EXPECT_EQ(markup, markup_result); -#if defined(OS_MACOSX) - // TODO(playmobil): It's not clear that the OS X clipboard needs to support +#if defined(OS_WIN) + // TODO(playmobil): It's not clear that non windows clipboards need to support // this. -#else EXPECT_EQ(url, url_result); #endif } +// TODO(estade): Port the following tests. +#if !defined(OS_LINUX) TEST_F(ClipboardTest, TrickyHTMLTest) { Clipboard clipboard; @@ -221,3 +224,4 @@ TEST_F(ClipboardTest, BitmapTest) { Clipboard::GetBitmapFormatType())); } #endif +#endif // !defined(OS_LINUX) diff --git a/base/test_suite.h b/base/test_suite.h index ae5faf1..6b6dfd5 100644 --- a/base/test_suite.h +++ b/base/test_suite.h @@ -19,6 +19,8 @@ #if defined(OS_WIN) #include <windows.h> #include "base/multiprocess_test.h" +#elif defined(OS_LINUX) +#include <gtk/gtk.h> #endif class TestSuite { @@ -26,6 +28,9 @@ class TestSuite { TestSuite(int argc, char** argv) { CommandLine::SetArgcArgv(argc, argv); testing::InitGoogleTest(&argc, argv); +#if defined(OS_LINUX) + gtk_init_check(&argc, &argv); +#endif } virtual ~TestSuite() {} |