summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/web_contents/web_drag_source_gtk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/web_contents/web_drag_source_gtk.cc')
-rw-r--r--chromium/content/browser/web_contents/web_drag_source_gtk.cc403
1 files changed, 0 insertions, 403 deletions
diff --git a/chromium/content/browser/web_contents/web_drag_source_gtk.cc b/chromium/content/browser/web_contents/web_drag_source_gtk.cc
deleted file mode 100644
index 2f9e58707f9..00000000000
--- a/chromium/content/browser/web_contents/web_drag_source_gtk.cc
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright (c) 2012 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 "content/browser/web_contents/web_drag_source_gtk.h"
-
-#include <string>
-
-#include "base/nix/mime_util_xdg.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_restrictions.h"
-#include "content/browser/download/drag_download_file.h"
-#include "content/browser/download/drag_download_util.h"
-#include "content/browser/renderer_host/render_view_host_delegate.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/web_contents/drag_utils_gtk.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/web_contents_view.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/drop_data.h"
-#include "net/base/file_stream.h"
-#include "net/base/net_util.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/clipboard/custom_data_helper.h"
-#include "ui/base/dragdrop/gtk_dnd_util.h"
-#include "ui/base/gtk/gtk_screen_util.h"
-#include "ui/gfx/gtk_compat.h"
-#include "ui/gfx/gtk_util.h"
-
-using blink::WebDragOperation;
-using blink::WebDragOperationsMask;
-using blink::WebDragOperationNone;
-
-namespace content {
-
-WebDragSourceGtk::WebDragSourceGtk(WebContents* web_contents)
- : web_contents_(static_cast<WebContentsImpl*>(web_contents)),
- drag_pixbuf_(NULL),
- drag_failed_(false),
- drag_widget_(gtk_invisible_new()),
- drag_context_(NULL),
- drag_icon_(gtk_window_new(GTK_WINDOW_POPUP)) {
- signals_.Connect(drag_widget_, "drag-failed",
- G_CALLBACK(OnDragFailedThunk), this);
- signals_.Connect(drag_widget_, "drag-begin",
- G_CALLBACK(OnDragBeginThunk),
- this);
- signals_.Connect(drag_widget_, "drag-end",
- G_CALLBACK(OnDragEndThunk), this);
- signals_.Connect(drag_widget_, "drag-data-get",
- G_CALLBACK(OnDragDataGetThunk), this);
-
- signals_.Connect(drag_icon_, "expose-event",
- G_CALLBACK(OnDragIconExposeThunk), this);
-}
-
-WebDragSourceGtk::~WebDragSourceGtk() {
- // Break the current drag, if any.
- if (drop_data_) {
- gtk_grab_add(drag_widget_);
- gtk_grab_remove(drag_widget_);
- base::MessageLoopForUI::current()->RemoveObserver(this);
- drop_data_.reset();
- }
-
- gtk_widget_destroy(drag_widget_);
- gtk_widget_destroy(drag_icon_);
-}
-
-bool WebDragSourceGtk::StartDragging(const DropData& drop_data,
- WebDragOperationsMask allowed_ops,
- GdkEventButton* last_mouse_down,
- const SkBitmap& image,
- const gfx::Vector2d& image_offset) {
- // Guard against re-starting before previous drag completed.
- if (drag_context_) {
- NOTREACHED();
- return false;
- }
-
- int targets_mask = 0;
-
- if (!drop_data.text.string().empty())
- targets_mask |= ui::TEXT_PLAIN;
- if (drop_data.url.is_valid()) {
- targets_mask |= ui::TEXT_URI_LIST;
- targets_mask |= ui::CHROME_NAMED_URL;
- targets_mask |= ui::NETSCAPE_URL;
- }
- if (!drop_data.html.string().empty())
- targets_mask |= ui::TEXT_HTML;
- if (!drop_data.file_contents.empty())
- targets_mask |= ui::CHROME_WEBDROP_FILE_CONTENTS;
- if (!drop_data.download_metadata.empty() &&
- ParseDownloadMetadata(drop_data.download_metadata,
- &wide_download_mime_type_,
- &download_file_name_,
- &download_url_)) {
- targets_mask |= ui::DIRECT_SAVE_FILE;
- }
- if (!drop_data.custom_data.empty())
- targets_mask |= ui::CUSTOM_DATA;
-
- // NOTE: Begin a drag even if no targets present. Otherwise, things like
- // draggable list elements will not work.
-
- drop_data_.reset(new DropData(drop_data));
-
- // The image we get from WebKit makes heavy use of alpha-shading. This looks
- // bad on non-compositing WMs. Fall back to the default drag icon.
- if (!image.isNull() && ui::IsScreenComposited())
- drag_pixbuf_ = gfx::GdkPixbufFromSkBitmap(image);
- image_offset_ = image_offset;
-
- GtkTargetList* list = ui::GetTargetListFromCodeMask(targets_mask);
- if (targets_mask & ui::CHROME_WEBDROP_FILE_CONTENTS) {
- // Looking up the mime type can hit the disk. http://crbug.com/84896
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- drag_file_mime_type_ = gdk_atom_intern(
- base::nix::GetDataMimeType(drop_data.file_contents).c_str(), FALSE);
- gtk_target_list_add(list, drag_file_mime_type_,
- 0, ui::CHROME_WEBDROP_FILE_CONTENTS);
- }
-
- drag_failed_ = false;
- // If we don't pass an event, GDK won't know what event time to start grabbing
- // mouse events. Technically it's the mouse motion event and not the mouse
- // down event that causes the drag, but there's no reliable way to know
- // *which* motion event initiated the drag, so this will have to do.
- // TODO(estade): This can sometimes be very far off, e.g. if the user clicks
- // and holds and doesn't start dragging for a long time. I doubt it matters
- // much, but we should probably look into the possibility of getting the
- // initiating event from webkit.
- drag_context_ = gtk_drag_begin(drag_widget_, list,
- WebDragOpToGdkDragAction(allowed_ops),
- 1, // Drags are always initiated by the left button.
- reinterpret_cast<GdkEvent*>(last_mouse_down));
- // The drag adds a ref; let it own the list.
- gtk_target_list_unref(list);
-
- // Sometimes the drag fails to start; |context| will be NULL and we won't
- // get a drag-end signal.
- if (!drag_context_) {
- drag_failed_ = true;
- drop_data_.reset();
- return false;
- }
-
- base::MessageLoopForUI::current()->AddObserver(this);
- return true;
-}
-
-void WebDragSourceGtk::WillProcessEvent(GdkEvent* event) {
- // No-op.
-}
-
-void WebDragSourceGtk::DidProcessEvent(GdkEvent* event) {
- if (event->type != GDK_MOTION_NOTIFY)
- return;
-
- GdkEventMotion* event_motion = reinterpret_cast<GdkEventMotion*>(event);
- gfx::Point client = ui::ClientPoint(GetContentNativeView());
-
- if (web_contents_) {
- web_contents_->DragSourceMovedTo(
- client.x(), client.y(),
- static_cast<int>(event_motion->x_root),
- static_cast<int>(event_motion->y_root));
- }
-}
-
-void WebDragSourceGtk::OnDragDataGet(GtkWidget* sender,
- GdkDragContext* context,
- GtkSelectionData* selection_data,
- guint target_type,
- guint time) {
- const int kBitsPerByte = 8;
-
- switch (target_type) {
- case ui::TEXT_PLAIN: {
- std::string utf8_text = UTF16ToUTF8(drop_data_->text.string());
- gtk_selection_data_set_text(selection_data, utf8_text.c_str(),
- utf8_text.length());
- break;
- }
-
- case ui::TEXT_HTML: {
- // TODO(estade): change relative links to be absolute using
- // |html_base_url|.
- std::string utf8_text = UTF16ToUTF8(drop_data_->html.string());
- gtk_selection_data_set(selection_data,
- ui::GetAtomForTarget(ui::TEXT_HTML),
- kBitsPerByte,
- reinterpret_cast<const guchar*>(utf8_text.c_str()),
- utf8_text.length());
- break;
- }
-
- case ui::TEXT_URI_LIST:
- case ui::CHROME_NAMED_URL:
- case ui::NETSCAPE_URL: {
- ui::WriteURLWithName(selection_data, drop_data_->url,
- drop_data_->url_title, target_type);
- break;
- }
-
- case ui::CHROME_WEBDROP_FILE_CONTENTS: {
- gtk_selection_data_set(
- selection_data,
- drag_file_mime_type_, kBitsPerByte,
- reinterpret_cast<const guchar*>(drop_data_->file_contents.data()),
- drop_data_->file_contents.length());
- break;
- }
-
- case ui::DIRECT_SAVE_FILE: {
- char status_code = 'E';
-
- // Retrieves the full file path (in file URL format) provided by the
- // drop target by reading from the source window's XdndDirectSave0
- // property.
- gint file_url_len = 0;
- guchar* file_url_value = NULL;
- if (gdk_property_get(context->source_window,
- ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE),
- ui::GetAtomForTarget(ui::TEXT_PLAIN_NO_CHARSET),
- 0,
- 1024,
- FALSE,
- NULL,
- NULL,
- &file_url_len,
- &file_url_value) &&
- file_url_value) {
- // Convert from the file url to the file path.
- GURL file_url(std::string(reinterpret_cast<char*>(file_url_value),
- file_url_len));
- g_free(file_url_value);
- base::FilePath file_path;
- if (net::FileURLToFilePath(file_url, &file_path)) {
- // Open the file as a stream.
- scoped_ptr<net::FileStream> file_stream(
- CreateFileStreamForDrop(
- &file_path,
- GetContentClient()->browser()->GetNetLog()));
- if (file_stream) {
- // Start downloading the file to the stream.
- scoped_refptr<DragDownloadFile> drag_file_downloader =
- new DragDownloadFile(
- file_path,
- file_stream.Pass(),
- download_url_,
- Referrer(web_contents_->GetURL(),
- drop_data_->referrer_policy),
- web_contents_->GetEncoding(),
- web_contents_);
- drag_file_downloader->Start(
- new PromiseFileFinalizer(drag_file_downloader.get()));
-
- // Set the status code to success.
- status_code = 'S';
- }
- }
-
- // Return the status code to the file manager.
- gtk_selection_data_set(selection_data,
- gtk_selection_data_get_target(selection_data),
- kBitsPerByte,
- reinterpret_cast<guchar*>(&status_code),
- 1);
- }
- break;
- }
-
- case ui::CUSTOM_DATA: {
- Pickle custom_data;
- ui::WriteCustomDataToPickle(drop_data_->custom_data, &custom_data);
- gtk_selection_data_set(
- selection_data,
- ui::GetAtomForTarget(ui::CUSTOM_DATA),
- kBitsPerByte,
- reinterpret_cast<const guchar*>(custom_data.data()),
- custom_data.size());
- break;
- }
-
- default:
- NOTREACHED();
- }
-}
-
-gboolean WebDragSourceGtk::OnDragFailed(GtkWidget* sender,
- GdkDragContext* context,
- GtkDragResult result) {
- drag_failed_ = true;
-
- gfx::Point root = ui::ScreenPoint(GetContentNativeView());
- gfx::Point client = ui::ClientPoint(GetContentNativeView());
-
- if (web_contents_) {
- web_contents_->DragSourceEndedAt(
- client.x(), client.y(), root.x(), root.y(),
- WebDragOperationNone);
- }
-
- // Let the native failure animation run.
- return FALSE;
-}
-
-void WebDragSourceGtk::OnDragBegin(GtkWidget* sender,
- GdkDragContext* drag_context) {
- if (!download_url_.is_empty()) {
- // Generate the file name based on both mime type and proposed file name.
- std::string default_name =
- GetContentClient()->browser()->GetDefaultDownloadName();
- base::FilePath generated_download_file_name =
- net::GenerateFileName(download_url_,
- std::string(),
- std::string(),
- download_file_name_.value(),
- UTF16ToUTF8(wide_download_mime_type_),
- default_name);
-
- // Pass the file name to the drop target by setting the source window's
- // XdndDirectSave0 property.
- gdk_property_change(drag_context->source_window,
- ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE),
- ui::GetAtomForTarget(ui::TEXT_PLAIN_NO_CHARSET),
- 8,
- GDK_PROP_MODE_REPLACE,
- reinterpret_cast<const guchar*>(
- generated_download_file_name.value().c_str()),
- generated_download_file_name.value().length());
- }
-
- if (drag_pixbuf_) {
- gtk_widget_set_size_request(drag_icon_,
- gdk_pixbuf_get_width(drag_pixbuf_),
- gdk_pixbuf_get_height(drag_pixbuf_));
-
- // We only need to do this once.
- if (!gtk_widget_get_realized(drag_icon_)) {
- GdkScreen* screen = gtk_widget_get_screen(drag_icon_);
- GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen);
- if (rgba)
- gtk_widget_set_colormap(drag_icon_, rgba);
- }
-
- gtk_drag_set_icon_widget(drag_context, drag_icon_,
- image_offset_.x(), image_offset_.y());
- }
-}
-
-void WebDragSourceGtk::OnDragEnd(GtkWidget* sender,
- GdkDragContext* drag_context) {
- if (drag_pixbuf_) {
- g_object_unref(drag_pixbuf_);
- drag_pixbuf_ = NULL;
- }
-
- base::MessageLoopForUI::current()->RemoveObserver(this);
-
- if (!download_url_.is_empty()) {
- gdk_property_delete(drag_context->source_window,
- ui::GetAtomForTarget(ui::DIRECT_SAVE_FILE));
- }
-
- if (!drag_failed_) {
- gfx::Point root = ui::ScreenPoint(GetContentNativeView());
- gfx::Point client = ui::ClientPoint(GetContentNativeView());
-
- if (web_contents_) {
- web_contents_->DragSourceEndedAt(
- client.x(), client.y(), root.x(), root.y(),
- GdkDragActionToWebDragOp(drag_context->action));
- }
- }
-
- web_contents_->SystemDragEnded();
-
- drop_data_.reset();
- drag_context_ = NULL;
-}
-
-gfx::NativeView WebDragSourceGtk::GetContentNativeView() const {
- return web_contents_->GetView()->GetContentNativeView();
-}
-
-gboolean WebDragSourceGtk::OnDragIconExpose(GtkWidget* sender,
- GdkEventExpose* event) {
- cairo_t* cr = gdk_cairo_create(event->window);
- gdk_cairo_rectangle(cr, &event->area);
- cairo_clip(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- gdk_cairo_set_source_pixbuf(cr, drag_pixbuf_, 0, 0);
- cairo_paint(cr);
- cairo_destroy(cr);
-
- return TRUE;
-}
-
-} // namespace content