15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/webplugin_delegate_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdkx.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/stats_counters.h" 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/plugin_instance.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/webplugin.h" 164311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch#include "content/public/common/content_constants.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_compat.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/blit.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/common/cursors/webcursor.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/npapi/bindings/npapi_x11.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebKeyboardEvent; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebInputEvent; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebMouseEvent; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace content { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginDelegateImpl::WebPluginDelegateImpl( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PluginInstance* instance) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : windowed_handle_(0), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windowed_did_set_window_(false), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windowless_(false), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_(NULL), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_(instance), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windowless_shm_pixmap_(None), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_(NULL), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_event_time_(-1.0), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plug_(NULL), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_(NULL), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quirks_(0), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_event_depth_(0), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_set_window_call_(true), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_has_focus_(false), 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_webkit_focus_(false), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing_view_has_focus_(true), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_succeeded_(false) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&window_, 0, sizeof(window_)); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance_->mime_type() == kFlashPluginSwfMimeType) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flash is tied to Firefox's whacky behavior with windowless plugins. See 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // comments in WindowlessPaint. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(viettrungluu): PLUGIN_QUIRK_WINDOWLESS_NO_RIGHT_CLICK: Don't allow 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // right-clicks in windowless content since Flash 10.1 (initial release, at 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // least) hangs in that case. Remove this once Flash is fixed. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quirks_ |= PLUGIN_QUIRK_WINDOWLESS_OFFSET_WINDOW_TO_DRAW 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) | PLUGIN_QUIRK_WINDOWLESS_INVALIDATE_AFTER_SET_WINDOW 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) | PLUGIN_QUIRK_WINDOWLESS_NO_RIGHT_CLICK; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(evanm): I played with this for quite a while but couldn't 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // figure out a way to make Flash not crash unless I didn't call 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPP_SetWindow. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, after piman's grand refactor of windowed plugins, maybe 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this is no longer necessary. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quirks_ |= PLUGIN_QUIRK_DONT_SET_NULL_WINDOW_HANDLE_ON_DESTROY; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebPluginDelegateImpl::~WebPluginDelegateImpl() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestroyInstance(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!windowless_) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowedDestroyWindow(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_.ws_info) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only ever use ws_info as an NPSetWindowCallbackStruct. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete static_cast<NPSetWindowCallbackStruct*>(window_.ws_info); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pixmap_) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_unref(pixmap_); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_ = NULL; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginDelegateImpl::PlatformInitialize() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::PluginWindowHandle handle = 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windowless_ ? 0 : gtk_plug_get_id(GTK_PLUG(plug_)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_->SetWindow(handle); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::PlatformDestroyInstance() { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nothing to do here. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& rect) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!windowless_ || !skia::SupportsPlatformPaint(canvas)) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skia::ScopedPlatformPaint scoped_platform_paint(canvas); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_t* context = scoped_platform_paint.GetPlatformSurface(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowlessPaint(context, rect); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginDelegateImpl::WindowedCreatePlugin() { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!windowed_handle_); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!plug_); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPP_GetValue() might write 4 bytes of data to this variable. Don't use a 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // single byte bool, use an int instead and make sure it is initialized. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int xembed = 0; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPError err = instance_->NPP_GetValue(NPPVpluginNeedsXEmbed, &xembed); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (err != NPERR_NO_ERROR || !xembed) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED() << " windowed plugin but without xembed. " 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "See http://code.google.com/p/chromium/issues/detail?id=38229"; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Passing 0 as the socket XID creates a plug without plugging it in a socket 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // yet, so that it can be latter added with gtk_socket_add_id(). 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plug_ = gtk_plug_new(0); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show(plug_); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = gtk_socket_new(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show(socket_); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_container_add(GTK_CONTAINER(plug_), socket_); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_show_all(plug_); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent the plug from being destroyed if the browser kills the container 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(plug_, "delete-event", G_CALLBACK(gtk_true), NULL); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent the socket from being destroyed when the plugin removes itself. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_signal_connect(socket_, "plug_removed", G_CALLBACK(gtk_true), NULL); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windowed_handle_ = gtk_socket_get_id(GTK_SOCKET(socket_)); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.window = reinterpret_cast<void*>(windowed_handle_); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window_.ws_info) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.ws_info = new NPSetWindowCallbackStruct; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPSetWindowCallbackStruct* extra = 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<NPSetWindowCallbackStruct*>(window_.ws_info); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->type = NP_SETWINDOW; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->display = GDK_DISPLAY(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int screen = DefaultScreen(GDK_DISPLAY()); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->visual = DefaultVisual(GDK_DISPLAY(), screen); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->depth = DefaultDepth(GDK_DISPLAY(), screen); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->colormap = DefaultColormap(GDK_DISPLAY(), screen); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::WindowedDestroyWindow() { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plug_) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_->WillDestroyWindow(gtk_plug_get_id(GTK_PLUG(plug_))); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_destroy(plug_); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plug_ = NULL; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = NULL; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windowed_handle_ = 0; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginDelegateImpl::WindowedReposition( 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& window_rect, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& clip_rect) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_rect == window_rect_ && clip_rect == clip_rect_) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_rect_ = window_rect; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip_rect_ = clip_rect; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::WindowedSetWindow() { 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!instance_.get()) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!windowed_handle_) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See https://bugzilla.mozilla.org/show_bug.cgi?id=108347 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we call NPP_SetWindow with a <= 0 width or height, problems arise in 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flash (and possibly other plugins). 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(piman): the Mozilla code suggests that for the Java plugin, we should 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // still call NPP_SetWindow in that case. We need to verify that. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_rect_.width() <= 0 || window_rect_.height() <= 0) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance()->set_window_handle(windowed_handle_); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!instance()->windowless()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.top = clip_rect_.y(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.left = clip_rect_.x(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.bottom = clip_rect_.y() + clip_rect_.height(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.right = clip_rect_.x() + clip_rect_.width(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.height = window_rect_.height(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.width = window_rect_.width(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.x = window_rect_.x(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.y = window_rect_.y(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.type = NPWindowTypeWindow; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset this flag before entering the instance in case of side-effects. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windowed_did_set_window_ = true; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPError err = instance()->NPP_SetWindow(&window_); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(err == NPERR_NO_ERROR); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::WindowlessUpdateGeometry( 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& window_rect, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& clip_rect) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only resend to the instance if the geometry has changed. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_rect == window_rect_ && clip_rect == clip_rect_) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip_rect_ = clip_rect; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_rect_ = window_rect; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowlessSetWindow(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::EnsurePixmapAtLeastSize(int width, int height) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pixmap_) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gint cur_width, cur_height; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_pixmap_get_size(pixmap_, &cur_width, &cur_height); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur_width >= width && cur_height >= height) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // We are already the appropriate size. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, we need to recreate ourselves. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_unref(pixmap_); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_ = NULL; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |sys_visual| is owned by gdk; we shouldn't free it. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkVisual* sys_visual = gdk_visual_get_system(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_ = gdk_pixmap_new(NULL, // use width/height/depth params 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(1, width), std::max(1, height), 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys_visual->depth); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(erg): Replace this with GdkVisual when we move to GTK3. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GdkColormap* colormap = gdk_colormap_new(gdk_visual_get_system(), 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALSE); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_drawable_set_colormap(pixmap_, colormap); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The GdkDrawable now owns the GdkColormap. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_object_unref(colormap); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RECTANGLES 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Draw a rectangle on a Cairo context. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Useful for debugging various rectangles involved in drawing plugins. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DrawDebugRectangle(cairo_t* cairo, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& rect, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float r, float g, float b) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_set_source_rgba(cairo, r, g, b, 0.5); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_rectangle(cairo, rect.x(), rect.y(), 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect.width(), rect.height()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_stroke(cairo); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& damage_rect) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compare to: 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://mxr.mozilla.org/firefox/source/layout/generic/nsObjectFrame.cpp: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nsPluginInstanceOwner::Renderer::NativeDraw(). 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(context); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(darin): we should avoid calling NPP_SetWindow here since it may 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cause page layout to be invalidated. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual dirty region is just the intersection of the plugin window and 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the clip window with the damage region. However, the plugin wants to draw 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // relative to the containing window's origin, so our pixmap must be from the 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window's origin down to the bottom-right edge of the dirty region. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Typical case: 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // X-----------------------------------+-----------------------------+ 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | pixmap +-------------------+ | 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | damage | window | 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | +---+-------------------+-------------+ | 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | clip | | 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | +---+---+-------------------+----------+ | | 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | | | | | 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | draw | | | | 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | | | | | 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +-------+---+---+-------------------+----------+--+ | 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | | | 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | +-------------------+ | | 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | plugin | | 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | +--------------------------------------+ | 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +-----------------------------------------------------------------+ 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // X = origin 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPAPI doesn't properly define which coordinates each of 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - window.clipRect, window.x and window.y in the SetWindow call 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - x and y in GraphicsExpose HandleEvent call 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are relative to, nor does it define what the pixmap is relative to. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Any sane values for them just don't work with the flash plugin. Firefox 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has some interesting behavior. Experiments showed that: 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - window.clipRect is always in the same space as window.x and window.y 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - in the first SetWindow call, or when scrolling, window.x and window.y are 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the coordinates of the plugin relative to the window. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - whenever only a part of the plugin is drawn, Firefox issues a SetWindow 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call before each GraphicsExpose event, that sets the drawing origin to 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (0, 0) as if the plugin was scrolled to be partially out of the view. The 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GraphicsExpose event has coordinates relative to the "window" (assuming 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that virtual scroll). The pixmap is also relative to the window. It always 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sets the clip rect to the draw rect. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempts to deviate from that makes Flash render at the wrong place in the 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pixmap, or render the wrong pixels. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flash plugin: 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // X-----------------------------------------------------------------+ 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | +-------------------+ "real" window | 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | damage | | 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | +---+-------------------+-------------+ | 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | | "real" clip | | 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | +---+---O===================#==========#==#===============# 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | H draw | | | H 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | H = pixmap | | | H 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | | H = "apparent" clip | | | H 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | + +---#-------------------+----------+--+ H 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | H | | H 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | H-------------------+ | H 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | H | H 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | | H plugin | H 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | +-------#------------------------------+ H 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | H H 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // | H "apparent" window H 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +---------------#=================================================# 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // X = "real" origin 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // O = "apparent" origin 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "real" means as seen by Chrome 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "apparent" means as seen by the plugin. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect draw_rect = gfx::IntersectRects(window_rect_, damage_rect); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clip_rect_ is relative to the plugin 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect clip_rect_window = clip_rect_; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip_rect_window.Offset(window_rect_.x(), window_rect_.y()); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) draw_rect.Intersect(clip_rect_window); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These offsets represent by how much the view is shifted to accomodate 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flash (the coordinates of X relative to O in the diagram above). 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset_x = 0; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset_y = 0; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quirks_ & PLUGIN_QUIRK_WINDOWLESS_OFFSET_WINDOW_TO_DRAW) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_x = -draw_rect.x(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset_y = -draw_rect.y(); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.top = 0; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.left = 0; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.bottom = draw_rect.height(); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.right = draw_rect.width(); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.height = window_rect_.height(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.width = window_rect_.width(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.x = window_rect_.x() - draw_rect.x(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.y = window_rect_.y() - draw_rect.y(); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.type = NPWindowTypeDrawable; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(window_.ws_info); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPError err = instance()->NPP_SetWindow(&window_); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(err, NPERR_NO_ERROR); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect pixmap_draw_rect = draw_rect; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_draw_rect.Offset(offset_x, offset_y); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect pixmap_rect(0, 0, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_draw_rect.right(), 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_draw_rect.bottom()); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the paint message, targeting the pixmap. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPEvent np_event = {0}; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XGraphicsExposeEvent& event = np_event.xgraphicsexpose; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.type = GraphicsExpose; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.x = pixmap_draw_rect.x(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.y = pixmap_draw_rect.y(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.width = pixmap_draw_rect.width(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.height = pixmap_draw_rect.height(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.display = GDK_DISPLAY(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (windowless_shm_pixmap_ != None) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pixmap pixmap = None; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GC xgc = NULL; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Display* display = event.display; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect plugin_draw_rect = draw_rect; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make plugin_draw_rect relative to the plugin window. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_draw_rect.Offset(-window_rect_.x(), -window_rect_.y()); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case the drawing area does not start with the plugin window origin, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we can not let the plugin directly draw over the shared memory pixmap. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plugin_draw_rect.x() != pixmap_draw_rect.x() || 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_draw_rect.y() != pixmap_draw_rect.y()) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap = XCreatePixmap(display, windowless_shm_pixmap_, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(1, pixmap_rect.width()), 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(1, pixmap_rect.height()), 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultDepth(display, DefaultScreen(display))); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xgc = XCreateGC(display, windowless_shm_pixmap_, 0, NULL); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the current image into the pixmap, so the plugin can draw over it. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XCopyArea(display, windowless_shm_pixmap_, pixmap, xgc, 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_draw_rect.x(), plugin_draw_rect.y(), 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_draw_rect.width(), pixmap_draw_rect.height(), 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_draw_rect.x(), pixmap_draw_rect.y()); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.drawable = pixmap; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.drawable = windowless_shm_pixmap_; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the plugin to paint into the pixmap. 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StatsRate plugin_paint("Plugin.Paint"); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StatsScope<base::StatsRate> scope(plugin_paint); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance()->NPP_HandleEvent(&np_event); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pixmap != None) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the rendered image pixmap back into the shm pixmap 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and thus the drawing buffer. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XCopyArea(display, pixmap, windowless_shm_pixmap_, xgc, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_draw_rect.x(), pixmap_draw_rect.y(), 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pixmap_draw_rect.width(), pixmap_draw_rect.height(), 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_draw_rect.x(), plugin_draw_rect.y()); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSync(display, FALSE); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xgc) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFreeGC(display, xgc); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFreePixmap(display, pixmap); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSync(display, FALSE); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height()); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the current image into the pixmap, so the plugin can draw over 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this background. 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_t* cairo = gdk_cairo_create(pixmap_); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_destroy(cairo); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.drawable = GDK_PIXMAP_XID(pixmap_); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the plugin to paint into the pixmap. 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StatsRate plugin_paint("Plugin.Paint"); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StatsScope<base::StatsRate> scope(plugin_paint); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance()->NPP_HandleEvent(&np_event); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_save(context); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now copy the rendered image pixmap back into the drawing buffer. 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_rectangle(context, draw_rect.x(), draw_rect.y(), 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) draw_rect.width(), draw_rect.height()); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_clip(context); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_paint(context); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RECTANGLES 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Draw some debugging rectangles. 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pixmap rect = blue. 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawDebugRectangle(context, pixmap_rect, 0, 0, 1); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drawing rect = red. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DrawDebugRectangle(context, draw_rect, 1, 0, 0); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_restore(context); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebPluginDelegateImpl::WindowlessSetWindow() { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!instance()) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_rect_.IsEmpty()) // wait for geometry to be set. 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(instance()->windowless()); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mozilla docs say that this window param is not used for windowless 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plugins; rather, the window is passed during the GraphicsExpose event. 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(window_.window, static_cast<void*>(NULL)); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.top = clip_rect_.y() + window_rect_.y(); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.left = clip_rect_.x() + window_rect_.x(); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.bottom = 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip_rect_.y() + clip_rect_.height() + window_rect_.y(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.clipRect.right = 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip_rect_.x() + clip_rect_.width() + window_rect_.x(); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.height = window_rect_.height(); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.width = window_rect_.width(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.x = window_rect_.x(); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.y = window_rect_.y(); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.type = NPWindowTypeDrawable; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window_.ws_info) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_.ws_info = new NPSetWindowCallbackStruct; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPSetWindowCallbackStruct* extra = 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<NPSetWindowCallbackStruct*>(window_.ws_info); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->display = GDK_DISPLAY(); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int screen = DefaultScreen(GDK_DISPLAY()); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->visual = DefaultVisual(GDK_DISPLAY(), screen); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->depth = DefaultDepth(GDK_DISPLAY(), screen); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra->colormap = DefaultColormap(GDK_DISPLAY(), screen); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPError err = instance()->NPP_SetWindow(&window_); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(err == NPERR_NO_ERROR); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quirks_ & PLUGIN_QUIRK_WINDOWLESS_INVALIDATE_AFTER_SET_WINDOW) { 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After a NPP_SetWindow, Flash cancels its timer that generates the 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // invalidates until it gets a paint event, but doesn't explicitly call 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NPP_InvalidateRect. 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_->InvalidateRect(clip_rect_); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(instance()->windowless()); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPEvent np_event = {0}; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XFocusChangeEvent& event = np_event.xfocus; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.type = focused ? FocusIn : FocusOut; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.display = GDK_DISPLAY(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same values as Firefox. .serial and .window stay 0. 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.mode = -1; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.detail = NotifyDetailNone; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance()->NPP_HandleEvent(&np_event); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts a WebInputEvent::Modifiers bitfield into a 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// corresponding X modifier state. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int GetXModifierState(int modifiers) { 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x_state = 0; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifiers & WebInputEvent::ControlKey) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_state |= ControlMask; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifiers & WebInputEvent::ShiftKey) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_state |= ShiftMask; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifiers & WebInputEvent::AltKey) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_state |= Mod1Mask; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifiers & WebInputEvent::MetaKey) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_state |= Mod2Mask; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifiers & WebInputEvent::LeftButtonDown) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_state |= Button1Mask; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifiers & WebInputEvent::MiddleButtonDown) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_state |= Button2Mask; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modifiers & WebInputEvent::RightButtonDown) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x_state |= Button3Mask; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(piman@google.com): There are other modifiers, e.g. Num Lock, that 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be set (and Firefox does), but we didn't keep the information in 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the WebKit event. 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x_state; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPEventFromWebMouseEvent(const WebMouseEvent& event, 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time timestamp, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPEvent* np_event) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->xany.display = GDK_DISPLAY(); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Firefox keeps xany.serial and xany.window as 0. 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int modifier_state = GetXModifierState(event.modifiers); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window root = GDK_ROOT_WINDOW(); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event.type) { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseMove: { 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->type = MotionNotify; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XMotionEvent& motion_event = np_event->xmotion; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.root = root; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.time = timestamp; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.x = event.x; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.y = event.y; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.x_root = event.globalX; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.y_root = event.globalY; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.state = modifier_state; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.is_hint = NotifyNormal; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) motion_event.same_screen = True; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseLeave: 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseEnter: { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.type == WebInputEvent::MouseEnter) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->type = EnterNotify; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->type = LeaveNotify; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XCrossingEvent& crossing_event = np_event->xcrossing; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.root = root; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.time = timestamp; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.x = event.x; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.y = event.y; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.x_root = event.globalX; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.y_root = event.globalY; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.mode = -1; // This is what Firefox sets it to. 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.detail = NotifyDetailNone; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.same_screen = True; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(piman@google.com): set this to the correct value. Firefox does. I 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // don't know where to get the information though, we get focus 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications, but no unfocus. 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.focus = 0; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crossing_event.state = modifier_state; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseUp: 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseDown: { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.type == WebInputEvent::MouseDown) { 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->type = ButtonPress; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->type = ButtonRelease; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XButtonEvent& button_event = np_event->xbutton; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.root = root; 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.time = timestamp; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.x = event.x; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.y = event.y; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.x_root = event.globalX; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.y_root = event.globalY; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.state = modifier_state; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event.button) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebMouseEvent::ButtonLeft: 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.button = Button1; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebMouseEvent::ButtonMiddle: 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.button = Button2; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebMouseEvent::ButtonRight: 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.button = Button3; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_event.same_screen = True; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPEventFromWebKeyboardEvent(const WebKeyboardEvent& event, 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time timestamp, 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPEvent* np_event) { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->xany.display = GDK_DISPLAY(); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Firefox keeps xany.serial and xany.window as 0. 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event.type) { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebKeyboardEvent::KeyDown: 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->type = KeyPress; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebKeyboardEvent::KeyUp: 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) np_event->type = KeyRelease; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XKeyEvent& key_event = np_event->xkey; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.send_event = False; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.display = GDK_DISPLAY(); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Firefox keeps xany.serial and xany.window as 0. 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(piman@google.com): is this right for multiple screens ? 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.root = DefaultRootWindow(key_event.display); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.time = timestamp; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: We don't have the correct information for x/y/x_root/y_root. Firefox 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // doesn't have it either, so we pass the same values. 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.x = 0; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.y = 0; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.x_root = -1; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.y_root = -1; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.state = GetXModifierState(event.modifiers); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.keycode = event.nativeKeyCode; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_event.same_screen = True; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool NPEventFromWebInputEvent(const WebInputEvent& event, 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time timestamp, 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPEvent* np_event) { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (event.type) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseMove: 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseLeave: 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseEnter: 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseDown: 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::MouseUp: 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.size < sizeof(WebMouseEvent)) { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPEventFromWebMouseEvent( 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *static_cast<const WebMouseEvent*>(&event), timestamp, np_event); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::KeyDown: 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WebInputEvent::KeyUp: 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.size < sizeof(WebKeyboardEvent)) { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPEventFromWebKeyboardEvent( 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *static_cast<const WebKeyboardEvent*>(&event), timestamp, np_event); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebPluginDelegateImpl::PlatformHandleInputEvent( 71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const WebInputEvent& event, WebCursor::CursorInfo* cursor_info) { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_event_time_ < 0.0) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_event_time_ = event.timeStampSeconds; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time timestamp = static_cast<Time>( 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (event.timeStampSeconds - first_event_time_) * 1.0e3); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPEvent np_event = {0}; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!NPEventFromWebInputEvent(event, timestamp, &np_event)) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See comment about PLUGIN_QUIRK_WINDOWLESS_NO_RIGHT_CLICK in constructor. 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (windowless_ && 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (quirks_ & PLUGIN_QUIRK_WINDOWLESS_NO_RIGHT_CLICK) && 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (np_event.type == ButtonPress || np_event.type == ButtonRelease) && 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (np_event.xbutton.button == Button3)) { 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = instance()->NPP_HandleEvent(&np_event) != 0; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flash always returns false, even when the event is handled. 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = true; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event->event == WM_MOUSEMOVE) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Snag a reference to the current cursor ASAP in case the plugin modified 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it. There is a nasty race condition here with the multiprocess browser 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as someone might be setting the cursor in the main process as well. 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *cursor = current_windowless_cursor_; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 751ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} // namespace content 752