OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/clipboard.h" | 5 #include "base/clipboard.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 | 85 |
86 // Called on GdkPixbuf destruction; see WriteBitmap(). | 86 // Called on GdkPixbuf destruction; see WriteBitmap(). |
87 void GdkPixbufFree(guchar* pixels, gpointer data) { | 87 void GdkPixbufFree(guchar* pixels, gpointer data) { |
88 free(pixels); | 88 free(pixels); |
89 } | 89 } |
90 | 90 |
91 } // namespace | 91 } // namespace |
92 | 92 |
93 Clipboard::Clipboard() { | 93 Clipboard::Clipboard() { |
94 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); | 94 clipboard_ = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); |
| 95 primary_selection_ = gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
95 } | 96 } |
96 | 97 |
97 Clipboard::~Clipboard() { | 98 Clipboard::~Clipboard() { |
98 // TODO(estade): do we want to save clipboard data after we exit? | 99 // TODO(estade): do we want to save clipboard data after we exit? |
99 // gtk_clipboard_set_can_store and gtk_clipboard_store work | 100 // gtk_clipboard_set_can_store and gtk_clipboard_store work |
100 // but have strangely awful performance. | 101 // but have strangely awful performance. |
101 } | 102 } |
102 | 103 |
103 void Clipboard::WriteObjects(const ObjectMap& objects) { | 104 void Clipboard::WriteObjects(const ObjectMap& objects) { |
104 clipboard_data_ = new TargetMap(); | 105 clipboard_data_ = new TargetMap(); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 const char* data_data, size_t data_len) { | 201 const char* data_data, size_t data_len) { |
201 char* data = new char[data_len]; | 202 char* data = new char[data_len]; |
202 memcpy(data, data_data, data_len); | 203 memcpy(data, data_data, data_len); |
203 std::string format(format_name, format_len); | 204 std::string format(format_name, format_len); |
204 InsertMapping(format.c_str(), data, data_len); | 205 InsertMapping(format.c_str(), data, data_len); |
205 } | 206 } |
206 | 207 |
207 // We do not use gtk_clipboard_wait_is_target_available because of | 208 // We do not use gtk_clipboard_wait_is_target_available because of |
208 // a bug with the gtk clipboard. It caches the available targets | 209 // a bug with the gtk clipboard. It caches the available targets |
209 // and does not always refresh the cache when it is appropriate. | 210 // and does not always refresh the cache when it is appropriate. |
210 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format) const { | 211 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, |
| 212 Clipboard::Buffer buffer) const { |
| 213 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 214 if (clipboard == NULL) |
| 215 return false; |
| 216 |
211 bool format_is_plain_text = GetPlainTextFormatType() == format; | 217 bool format_is_plain_text = GetPlainTextFormatType() == format; |
212 if (format_is_plain_text) { | 218 if (format_is_plain_text) { |
213 // This tries a number of common text targets. | 219 // This tries a number of common text targets. |
214 if (gtk_clipboard_wait_is_text_available(clipboard_)) | 220 if (gtk_clipboard_wait_is_text_available(clipboard)) |
215 return true; | 221 return true; |
216 } | 222 } |
217 | 223 |
218 bool retval = false; | 224 bool retval = false; |
219 GdkAtom* targets = NULL; | 225 GdkAtom* targets = NULL; |
220 GtkSelectionData* data = | 226 GtkSelectionData* data = |
221 gtk_clipboard_wait_for_contents(clipboard_, | 227 gtk_clipboard_wait_for_contents(clipboard, |
222 gdk_atom_intern("TARGETS", false)); | 228 gdk_atom_intern("TARGETS", false)); |
223 | 229 |
224 if (!data) | 230 if (!data) |
225 return false; | 231 return false; |
226 | 232 |
227 int num = 0; | 233 int num = 0; |
228 gtk_selection_data_get_targets(data, &targets, &num); | 234 gtk_selection_data_get_targets(data, &targets, &num); |
229 | 235 |
230 // Some programs post data to the clipboard without any targets. If this is | 236 // Some programs post data to the clipboard without any targets. If this is |
231 // the case we attempt to make sense of the contents as text. This is pretty | 237 // the case we attempt to make sense of the contents as text. This is pretty |
232 // unfortunate since it means we have to actually copy the data to see if it | 238 // unfortunate since it means we have to actually copy the data to see if it |
233 // is available, but at least this path shouldn't be hit for conforming | 239 // is available, but at least this path shouldn't be hit for conforming |
234 // programs. | 240 // programs. |
235 if (num <= 0) { | 241 if (num <= 0) { |
236 if (format_is_plain_text) { | 242 if (format_is_plain_text) { |
237 gchar* text = gtk_clipboard_wait_for_text(clipboard_); | 243 gchar* text = gtk_clipboard_wait_for_text(clipboard); |
238 if (text) { | 244 if (text) { |
239 g_free(text); | 245 g_free(text); |
240 retval = true; | 246 retval = true; |
241 } | 247 } |
242 } | 248 } |
243 } | 249 } |
244 | 250 |
245 GdkAtom format_atom = StringToGdkAtom(format); | 251 GdkAtom format_atom = StringToGdkAtom(format); |
246 | 252 |
247 for (int i = 0; i < num; i++) { | 253 for (int i = 0; i < num; i++) { |
248 if (targets[i] == format_atom) { | 254 if (targets[i] == format_atom) { |
249 retval = true; | 255 retval = true; |
250 break; | 256 break; |
251 } | 257 } |
252 } | 258 } |
253 | 259 |
254 g_free(targets); | 260 g_free(targets); |
255 gtk_selection_data_free(data); | 261 gtk_selection_data_free(data); |
256 | 262 |
257 return retval; | 263 return retval; |
258 } | 264 } |
259 | 265 |
260 bool Clipboard::IsFormatAvailableByString(const std::string& format) const { | 266 bool Clipboard::IsFormatAvailableByString(const std::string& format, |
261 return IsFormatAvailable(format); | 267 Clipboard::Buffer buffer) const { |
| 268 return IsFormatAvailable(format, buffer); |
262 } | 269 } |
263 | 270 |
264 void Clipboard::ReadText(string16* result) const { | 271 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { |
| 272 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 273 if (clipboard == NULL) |
| 274 return; |
| 275 |
265 result->clear(); | 276 result->clear(); |
266 gchar* text = gtk_clipboard_wait_for_text(clipboard_); | 277 gchar* text = gtk_clipboard_wait_for_text(clipboard); |
267 | 278 |
268 if (text == NULL) | 279 if (text == NULL) |
269 return; | 280 return; |
270 | 281 |
271 // TODO(estade): do we want to handle the possible error here? | 282 // TODO(estade): do we want to handle the possible error here? |
272 UTF8ToUTF16(text, strlen(text), result); | 283 UTF8ToUTF16(text, strlen(text), result); |
273 g_free(text); | 284 g_free(text); |
274 } | 285 } |
275 | 286 |
276 void Clipboard::ReadAsciiText(std::string* result) const { | 287 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, |
| 288 std::string* result) const { |
| 289 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 290 if (clipboard == NULL) |
| 291 return; |
| 292 |
277 result->clear(); | 293 result->clear(); |
278 gchar* text = gtk_clipboard_wait_for_text(clipboard_); | 294 gchar* text = gtk_clipboard_wait_for_text(clipboard); |
279 | 295 |
280 if (text == NULL) | 296 if (text == NULL) |
281 return; | 297 return; |
282 | 298 |
283 result->assign(text); | 299 result->assign(text); |
284 g_free(text); | 300 g_free(text); |
285 } | 301 } |
286 | 302 |
287 void Clipboard::ReadFile(FilePath* file) const { | 303 void Clipboard::ReadFile(FilePath* file) const { |
288 *file = FilePath(); | 304 *file = FilePath(); |
289 } | 305 } |
290 | 306 |
291 // TODO(estade): handle different charsets. | 307 // TODO(estade): handle different charsets. |
292 // TODO(port): set *src_url. | 308 // TODO(port): set *src_url. |
293 void Clipboard::ReadHTML(string16* markup, std::string* src_url) const { | 309 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, |
| 310 std::string* src_url) const { |
| 311 GtkClipboard* clipboard = LookupBackingClipboard(buffer); |
| 312 if (clipboard == NULL) |
| 313 return; |
294 markup->clear(); | 314 markup->clear(); |
295 | 315 |
296 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard_, | 316 GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, |
297 StringToGdkAtom(GetHtmlFormatType())); | 317 StringToGdkAtom(GetHtmlFormatType())); |
298 | 318 |
299 if (!data) | 319 if (!data) |
300 return; | 320 return; |
301 | 321 |
302 UTF8ToUTF16(reinterpret_cast<char*>(data->data), data->length, markup); | 322 UTF8ToUTF16(reinterpret_cast<char*>(data->data), data->length, markup); |
303 gtk_selection_data_free(data); | 323 gtk_selection_data_free(data); |
304 } | 324 } |
305 | 325 |
306 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 326 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 368 |
349 if (iter != clipboard_data_->end()) { | 369 if (iter != clipboard_data_->end()) { |
350 if (strcmp(kMimeBmp, key) == 0) | 370 if (strcmp(kMimeBmp, key) == 0) |
351 g_object_unref(reinterpret_cast<GdkPixbuf*>(iter->second.first)); | 371 g_object_unref(reinterpret_cast<GdkPixbuf*>(iter->second.first)); |
352 else | 372 else |
353 delete[] iter->second.first; | 373 delete[] iter->second.first; |
354 } | 374 } |
355 | 375 |
356 (*clipboard_data_)[key] = std::make_pair(data, data_len); | 376 (*clipboard_data_)[key] = std::make_pair(data, data_len); |
357 } | 377 } |
| 378 |
| 379 GtkClipboard* Clipboard::LookupBackingClipboard(Buffer clipboard) const { |
| 380 GtkClipboard* result; |
| 381 |
| 382 switch (clipboard) { |
| 383 case BUFFER_STANDARD: |
| 384 result = clipboard_; |
| 385 break; |
| 386 case BUFFER_SELECTION: |
| 387 result = primary_selection_; |
| 388 break; |
| 389 default: |
| 390 NOTREACHED(); |
| 391 result = NULL; |
| 392 break; |
| 393 } |
| 394 return result; |
| 395 } |
| 396 |
OLD | NEW |