1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block/* 2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 Martin Robinson <mrobinson@webkit.org> 321939df44de1705786c545cd1bf519d47250322dBen Murdoch * Copyright (C) Igalia S.L. 4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * All rights reserved. 5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * This library is free software; you can redistribute it and/or 7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modify it under the terms of the GNU Library General Public 8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * License as published by the Free Software Foundation; either 9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * version 2 of the License, or (at your option) any later version. 10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * This library is distributed in the hope that it will be useful, 12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * but WITHOUT ANY WARRANTY; without even the implied warranty of 13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Library General Public License for more details. 15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * You should have received a copy of the GNU Library General Public License 17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * along with this library; see the file COPYING.LIB. If not, write to 18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Boston, MA 02110-1301, USA. 20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "config.h" 23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "PasteboardHelper.h" 24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Chrome.h" 26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "DataObjectGtk.h" 27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Frame.h" 2806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "GtkVersioning.h" 29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Page.h" 30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Pasteboard.h" 3121939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "TextResourceDecoder.h" 32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <gtk/gtk.h> 33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/gobject/GOwnPtr.h> 34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocknamespace WebCore { 36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 37f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic GdkAtom textPlainAtom; 38f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic GdkAtom markupAtom; 39f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic GdkAtom netscapeURLAtom; 40f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic GdkAtom uriListAtom; 41f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic String gMarkupPrefix; 4228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 4328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic void removeMarkupPrefix(String& markup) 4428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{ 4528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 4628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu // The markup prefix is not harmful, but we remove it from the string anyway, so that 4728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu // we can have consistent results with other ports during the layout tests. 4828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (markup.startsWith(gMarkupPrefix)) 4928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu markup.remove(0, gMarkupPrefix.length()); 5028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu} 51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 52f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic void initGdkAtoms() 53f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 54f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch static gboolean initialized = FALSE; 55f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (initialized) 57f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 58f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 59f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch initialized = TRUE; 60f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 61f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch textPlainAtom = gdk_atom_intern("text/plain;charset=utf-8", FALSE); 62f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch markupAtom = gdk_atom_intern("text/html", FALSE); 63f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch netscapeURLAtom = gdk_atom_intern("_NETSCAPE_URL", FALSE); 64f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch uriListAtom = gdk_atom_intern("text/uri-list", FALSE); 65f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch gMarkupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"; 66f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 67f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPasteboardHelper::PasteboardHelper() 69dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : m_targetList(gtk_target_list_new(0, 0)) 70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 71f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch initGdkAtoms(); 72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPasteboardHelper::~PasteboardHelper() 75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_target_list_unref(m_targetList); 77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid PasteboardHelper::initializeTargetList() 80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_target_list_add_text_targets(m_targetList, getIdForTargetType(TargetTypeText)); 82e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke gtk_target_list_add(m_targetList, markupAtom, 0, getIdForTargetType(TargetTypeMarkup)); 8321939df44de1705786c545cd1bf519d47250322dBen Murdoch gtk_target_list_add_uri_targets(m_targetList, getIdForTargetType(TargetTypeURIList)); 8421939df44de1705786c545cd1bf519d47250322dBen Murdoch gtk_target_list_add(m_targetList, netscapeURLAtom, 0, getIdForTargetType(TargetTypeNetscapeURL)); 85e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke gtk_target_list_add_image_targets(m_targetList, getIdForTargetType(TargetTypeImage), TRUE); 86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic inline GtkWidget* widgetFromFrame(Frame* frame) 89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(frame); 91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Page* page = frame->page(); 92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(page); 93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Chrome* chrome = page->chrome(); 94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(chrome); 95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PlatformPageClient client = chrome->platformPageClient(); 96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(client); 97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return client; 98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockGtkClipboard* PasteboardHelper::getCurrentClipboard(Frame* frame) 101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (usePrimarySelectionClipboard(widgetFromFrame(frame))) 103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return getPrimarySelectionClipboard(frame); 104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return getClipboard(frame); 105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockGtkClipboard* PasteboardHelper::getClipboard(Frame* frame) const 108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return gtk_widget_get_clipboard(widgetFromFrame(frame), GDK_SELECTION_CLIPBOARD); 110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockGtkClipboard* PasteboardHelper::getPrimarySelectionClipboard(Frame* frame) const 113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return gtk_widget_get_clipboard(widgetFromFrame(frame), GDK_SELECTION_PRIMARY); 115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockGtkTargetList* PasteboardHelper::targetList() const 118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return m_targetList; 120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 122e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkestatic String selectionDataToUTF8String(GtkSelectionData* data) 123e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 124e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // g_strndup guards against selection data that is not null-terminated. 125e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke GOwnPtr<gchar> markupString(g_strndup(reinterpret_cast<const char*>(gtk_selection_data_get_data(data)), gtk_selection_data_get_length(data))); 126e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return String::fromUTF8(markupString.get()); 127e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 128e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 12921939df44de1705786c545cd1bf519d47250322dBen Murdochvoid PasteboardHelper::getClipboardContents(GtkClipboard* clipboard) 13021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 13121939df44de1705786c545cd1bf519d47250322dBen Murdoch DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); 13221939df44de1705786c545cd1bf519d47250322dBen Murdoch ASSERT(dataObject); 13321939df44de1705786c545cd1bf519d47250322dBen Murdoch 13421939df44de1705786c545cd1bf519d47250322dBen Murdoch if (gtk_clipboard_wait_is_text_available(clipboard)) { 13521939df44de1705786c545cd1bf519d47250322dBen Murdoch GOwnPtr<gchar> textData(gtk_clipboard_wait_for_text(clipboard)); 13621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (textData) 13721939df44de1705786c545cd1bf519d47250322dBen Murdoch dataObject->setText(String::fromUTF8(textData.get())); 13821939df44de1705786c545cd1bf519d47250322dBen Murdoch } 13921939df44de1705786c545cd1bf519d47250322dBen Murdoch 140e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (gtk_clipboard_wait_is_target_available(clipboard, markupAtom)) { 141e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, markupAtom)) { 14228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu String markup(selectionDataToUTF8String(data)); 14328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu removeMarkupPrefix(markup); 14428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu dataObject->setMarkup(markup); 145ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block gtk_selection_data_free(data); 146ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block } 14721939df44de1705786c545cd1bf519d47250322dBen Murdoch } 14821939df44de1705786c545cd1bf519d47250322dBen Murdoch 14921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (gtk_clipboard_wait_is_target_available(clipboard, uriListAtom)) { 15021939df44de1705786c545cd1bf519d47250322dBen Murdoch if (GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, uriListAtom)) { 151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch dataObject->setURIList(selectionDataToUTF8String(data)); 15221939df44de1705786c545cd1bf519d47250322dBen Murdoch gtk_selection_data_free(data); 15321939df44de1705786c545cd1bf519d47250322dBen Murdoch } 15421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 15521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 15621939df44de1705786c545cd1bf519d47250322dBen Murdoch 157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid PasteboardHelper::fillSelectionData(GtkSelectionData* selectionData, guint info, DataObjectGtk* dataObject) 158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (info == getIdForTargetType(TargetTypeText)) 160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_selection_data_set_text(selectionData, dataObject->text().utf8().data(), -1); 16121939df44de1705786c545cd1bf519d47250322dBen Murdoch 162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block else if (info == getIdForTargetType(TargetTypeMarkup)) { 16328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu // Some Linux applications refuse to accept pasted markup unless it is 16428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu // prefixed by a content-type meta tag. 16528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu CString markup = (gMarkupPrefix + dataObject->markup()).utf8(); 166e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke gtk_selection_data_set(selectionData, markupAtom, 8, 16728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu reinterpret_cast<const guchar*>(markup.data()), markup.length() + 1); 16821939df44de1705786c545cd1bf519d47250322dBen Murdoch 16921939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (info == getIdForTargetType(TargetTypeURIList)) { 170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch CString uriList = dataObject->uriList().utf8(); 171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch gtk_selection_data_set(selectionData, uriListAtom, 8, 172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch reinterpret_cast<const guchar*>(uriList.data()), uriList.length() + 1); 17321939df44de1705786c545cd1bf519d47250322dBen Murdoch 17421939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (info == getIdForTargetType(TargetTypeNetscapeURL) && dataObject->hasURL()) { 17521939df44de1705786c545cd1bf519d47250322dBen Murdoch String url(dataObject->url()); 17621939df44de1705786c545cd1bf519d47250322dBen Murdoch String result(url); 17721939df44de1705786c545cd1bf519d47250322dBen Murdoch result.append("\n"); 17821939df44de1705786c545cd1bf519d47250322dBen Murdoch 17921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dataObject->hasText()) 18021939df44de1705786c545cd1bf519d47250322dBen Murdoch result.append(dataObject->text()); 18121939df44de1705786c545cd1bf519d47250322dBen Murdoch else 18221939df44de1705786c545cd1bf519d47250322dBen Murdoch result.append(url); 18321939df44de1705786c545cd1bf519d47250322dBen Murdoch 18421939df44de1705786c545cd1bf519d47250322dBen Murdoch GOwnPtr<gchar> resultData(g_strdup(result.utf8().data())); 18506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen gtk_selection_data_set(selectionData, netscapeURLAtom, 8, 186ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block reinterpret_cast<const guchar*>(resultData.get()), strlen(resultData.get()) + 1); 18721939df44de1705786c545cd1bf519d47250322dBen Murdoch 18821939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (info == getIdForTargetType(TargetTypeImage)) 18921939df44de1705786c545cd1bf519d47250322dBen Murdoch gtk_selection_data_set_pixbuf(selectionData, dataObject->image()); 190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockGtkTargetList* PasteboardHelper::targetListForDataObject(DataObjectGtk* dataObject) 193dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 194dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GtkTargetList* list = gtk_target_list_new(0, 0); 195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (dataObject->hasText()) 197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_target_list_add_text_targets(list, getIdForTargetType(TargetTypeText)); 198dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 199dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (dataObject->hasMarkup()) 200e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke gtk_target_list_add(list, markupAtom, 0, getIdForTargetType(TargetTypeMarkup)); 201dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 20221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dataObject->hasURIList()) { 20321939df44de1705786c545cd1bf519d47250322dBen Murdoch gtk_target_list_add_uri_targets(list, getIdForTargetType(TargetTypeURIList)); 20421939df44de1705786c545cd1bf519d47250322dBen Murdoch gtk_target_list_add(list, netscapeURLAtom, 0, getIdForTargetType(TargetTypeNetscapeURL)); 20521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 20621939df44de1705786c545cd1bf519d47250322dBen Murdoch 20721939df44de1705786c545cd1bf519d47250322dBen Murdoch if (dataObject->hasImage()) 20821939df44de1705786c545cd1bf519d47250322dBen Murdoch gtk_target_list_add_image_targets(list, getIdForTargetType(TargetTypeImage), TRUE); 20921939df44de1705786c545cd1bf519d47250322dBen Murdoch 210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return list; 211dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 213e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid PasteboardHelper::fillDataObjectFromDropData(GtkSelectionData* data, guint info, DataObjectGtk* dataObject) 214e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 215e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (!gtk_selection_data_get_data(data)) 216e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return; 217e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 218e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke GdkAtom target = gtk_selection_data_get_target(data); 219e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (target == textPlainAtom) 220e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke dataObject->setText(selectionDataToUTF8String(data)); 22128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu else if (target == markupAtom) { 22228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu String markup(selectionDataToUTF8String(data)); 22328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu removeMarkupPrefix(markup); 22428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu dataObject->setMarkup(markup); 22528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu } else if (target == uriListAtom) { 226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch dataObject->setURIList(selectionDataToUTF8String(data)); 227e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } else if (target == netscapeURLAtom) { 228e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke String urlWithLabel(selectionDataToUTF8String(data)); 229e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke Vector<String> pieces; 230e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke urlWithLabel.split("\n", pieces); 231e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 232e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // Give preference to text/uri-list here, as it can hold more 233e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // than one URI but still take the label if there is one. 234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!dataObject->hasURIList()) 235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch dataObject->setURIList(pieces[0]); 236e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (pieces.size() > 1) 237e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke dataObject->setText(pieces[1]); 238e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 239e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 240e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 241e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkeVector<GdkAtom> PasteboardHelper::dropAtomsForContext(GtkWidget* widget, GdkDragContext* context) 242e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 243e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // Always search for these common atoms. 244e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke Vector<GdkAtom> dropAtoms; 245e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke dropAtoms.append(textPlainAtom); 246e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke dropAtoms.append(markupAtom); 247e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke dropAtoms.append(uriListAtom); 248e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke dropAtoms.append(netscapeURLAtom); 249e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 250e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke // For images, try to find the most applicable image type. 251cad810f21b803229eb11403f9209855525a25d57Steve Block GRefPtr<GtkTargetList> list(gtk_target_list_new(0, 0)); 252e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke gtk_target_list_add_image_targets(list.get(), getIdForTargetType(TargetTypeImage), TRUE); 253e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke GdkAtom atom = gtk_drag_dest_find_target(widget, context, list.get()); 254e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (atom != GDK_NONE) 255e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke dropAtoms.append(atom); 256e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 257e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return dropAtoms; 258e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 259e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic DataObjectGtk* settingClipboardDataObject = 0; 261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void getClipboardContentsCallback(GtkClipboard* clipboard, GtkSelectionData *selectionData, guint info, gpointer data) 263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); 265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(dataObject); 266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Pasteboard::generalPasteboard()->helper()->fillSelectionData(selectionData, info, dataObject); 267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 269dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void clearClipboardContentsCallback(GtkClipboard* clipboard, gpointer data) 270dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 271dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); 272dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(dataObject); 273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 274dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Only clear the DataObject for this clipboard if we are not currently setting it. 275dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (dataObject != settingClipboardDataObject) 276dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block dataObject->clear(); 277dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 278dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!data) 279dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 280dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 281dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GClosure* callback = static_cast<GClosure*>(data); 282dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GValue firstArgument = {0, {{0}}}; 283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block g_value_init(&firstArgument, G_TYPE_POINTER); 284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block g_value_set_pointer(&firstArgument, clipboard); 285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block g_closure_invoke(callback, 0, 1, &firstArgument, 0); 286dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block g_closure_unref(callback); 287dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 288dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 289dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid PasteboardHelper::writeClipboardContents(GtkClipboard* clipboard, GClosure* callback) 290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 291dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); 292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GtkTargetList* list = targetListForDataObject(dataObject); 293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int numberOfTargets; 295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block GtkTargetEntry* table = gtk_target_table_new_from_list(list, &numberOfTargets); 296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (numberOfTargets > 0 && table) { 298dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block settingClipboardDataObject = dataObject; 299dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 300dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_clipboard_set_with_data(clipboard, table, numberOfTargets, 301dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block getClipboardContentsCallback, clearClipboardContentsCallback, callback); 302967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch gtk_clipboard_set_can_store(clipboard, 0, 0); 303dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block settingClipboardDataObject = 0; 305dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else 307dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_clipboard_clear(clipboard); 308dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (table) 310dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_target_table_free(table, numberOfTargets); 311dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block gtk_target_list_unref(list); 312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 313dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 314dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 315dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 316