summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/data/npapi/convert_point.html27
-rw-r--r--chrome/test/ui/npapi_uitest.cc21
-rw-r--r--webkit/glue/plugins/plugin_instance.cc36
-rw-r--r--webkit/glue/plugins/plugin_instance.h9
-rw-r--r--webkit/glue/plugins/test/plugin_client.cc3
-rw-r--r--webkit/glue/plugins/test/plugin_windowless_test.cc93
-rw-r--r--webkit/glue/plugins/test/plugin_windowless_test.h1
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h7
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm2
9 files changed, 173 insertions, 26 deletions
diff --git a/chrome/test/data/npapi/convert_point.html b/chrome/test/data/npapi/convert_point.html
new file mode 100644
index 0000000..4c02529
--- /dev/null
+++ b/chrome/test/data/npapi/convert_point.html
@@ -0,0 +1,27 @@
+<html>
+
+<head>
+<script src="npapi.js"></script>
+</head>
+
+
+<body>
+<div id="statusPanel" style="border: 1px solid red; width: 100%">
+Test running....
+</div>
+
+
+NPAPI ConvertPoint test<p>
+Tests that NPN_ConvertPoint works.<P>
+
+<div style="position:absolute; left: 100px; top: 100px">
+<embed type="application/vnd.npapi-test"
+ src="foo"
+ name="convert_point"
+ id="1"
+ mode="np_embed"
+>
+</div>
+
+</body>
+</html>
diff --git a/chrome/test/ui/npapi_uitest.cc b/chrome/test/ui/npapi_uitest.cc
index e2d0336..f7df01f 100644
--- a/chrome/test/ui/npapi_uitest.cc
+++ b/chrome/test/ui/npapi_uitest.cc
@@ -428,3 +428,24 @@ TEST_F(NPAPIVisiblePluginTester, PluginReferrerTest) {
kTestCompleteSuccess, kShortWaitTimeout);
}
+#if defined(OS_MACOSX)
+TEST_F(NPAPIVisiblePluginTester, PluginConvertPointTest) {
+ if (UITest::in_process_renderer())
+ return;
+
+ scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
+ scoped_refptr<WindowProxy> window(browser->GetWindow());
+ window->SetBounds(gfx::Rect(100, 100, 600, 600));
+
+ GURL url(URLRequestMockHTTPJob::GetMockUrl(
+ FilePath(FILE_PATH_LITERAL("npapi/convert_point.html"))));
+ NavigateToURL(url);
+
+ // TODO(stuartmorgan): When the automation system supports sending clicks,
+ // change the test to trigger on mouse-down rather than window focus.
+ browser->BringToFront();
+ WaitForFinish("convert_point", "1", url, kTestCompleteCookie,
+ kTestCompleteSuccess, kShortWaitTimeout);
+}
+#endif
+
diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc
index f189e47..00ac91da 100644
--- a/webkit/glue/plugins/plugin_instance.cc
+++ b/webkit/glue/plugins/plugin_instance.cc
@@ -551,18 +551,20 @@ bool PluginInstance::ConvertPoint(double source_x, double source_y,
flipped_screen_x += plugin_origin_.x();
flipped_screen_y += plugin_origin_.y();
break;
+ case NPCoordinateSpaceWindow:
+ flipped_screen_x += containing_window_frame_.x();
+ flipped_screen_y = containing_window_frame_.height() - source_y +
+ containing_window_frame_.y();
+ break;
+ case NPCoordinateSpaceFlippedWindow:
+ flipped_screen_x += containing_window_frame_.x();
+ flipped_screen_y += containing_window_frame_.y();
+ break;
case NPCoordinateSpaceScreen:
flipped_screen_y = main_display_bounds.size.height - flipped_screen_y;
+ break;
case NPCoordinateSpaceFlippedScreen:
break;
- case NPCoordinateSpaceWindow:
- case NPCoordinateSpaceFlippedWindow:
- // Since a CG+Cocoa plugin has no way of getting a window reference, we
- // may be able to get away without implementing this for now. If we do
- // need to implement it later (e.g., for CALayer-based plugins) we'll need
- // to get window bounds over IPC.
- NOTIMPLEMENTED();
- return false;
default:
NOTREACHED();
return false;
@@ -575,18 +577,20 @@ bool PluginInstance::ConvertPoint(double source_x, double source_y,
target_x -= plugin_origin_.x();
target_y -= plugin_origin_.y();
break;
+ case NPCoordinateSpaceWindow:
+ target_x -= containing_window_frame_.x();
+ target_y -= containing_window_frame_.y();
+ target_y = containing_window_frame_.height() - target_y;
+ break;
+ case NPCoordinateSpaceFlippedWindow:
+ target_x -= containing_window_frame_.x();
+ target_y -= containing_window_frame_.y();
+ break;
case NPCoordinateSpaceScreen:
target_y = main_display_bounds.size.height - flipped_screen_y;
+ break;
case NPCoordinateSpaceFlippedScreen:
break;
- case NPCoordinateSpaceWindow:
- case NPCoordinateSpaceFlippedWindow:
- // Since a CG+Cocoa plugin has no way of getting a window reference, we
- // may be able to get away without implementing this for now. If we do
- // need to implement it later (e.g., for CALayer-based plugins) we'll need
- // to get window bounds over IPC.
- NOTIMPLEMENTED();
- return false;
default:
NOTREACHED();
return false;
diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h
index 6c2b0c2..19e4e33 100644
--- a/webkit/glue/plugins/plugin_instance.h
+++ b/webkit/glue/plugins/plugin_instance.h
@@ -18,6 +18,7 @@
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/gfx/point.h"
+#include "base/gfx/rect.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "webkit/glue/plugins/nphostapi.h"
@@ -114,7 +115,12 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
void set_event_model(int value) { event_model_ = value; }
// Updates the instance's tracking of the location of the plugin location
// relative to the upper left of the screen.
- void set_plugin_origin(gfx::Point origin) { plugin_origin_ = origin; }
+ void set_plugin_origin(const gfx::Point& origin) { plugin_origin_ = origin; }
+ // Updates the instance's tracking of the frame of the containing window
+ // relative to the upper left of the screen.
+ void set_window_frame(const gfx::Rect& frame) {
+ containing_window_frame_ = frame;
+ }
#endif
// Creates a stream for sending an URL. If notify_id is non-zero, it will
@@ -283,6 +289,7 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> {
int drawing_model_;
int event_model_;
gfx::Point plugin_origin_;
+ gfx::Rect containing_window_frame_;
NPCocoaEvent* currently_handled_event_; // weak
#endif
MessageLoop* message_loop_;
diff --git a/webkit/glue/plugins/test/plugin_client.cc b/webkit/glue/plugins/test/plugin_client.cc
index 3f2e6c7..0d0a76d 100644
--- a/webkit/glue/plugins/test/plugin_client.cc
+++ b/webkit/glue/plugins/test/plugin_client.cc
@@ -130,7 +130,8 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
test_name == "execute_script_delete_in_mouse_move" ||
test_name == "delete_frame_test" ||
test_name == "multiple_instances_sync_calls" ||
- test_name == "no_hang_if_init_crashes") {
+ test_name == "no_hang_if_init_crashes" ||
+ test_name == "convert_point") {
new_test = new NPAPIClient::WindowlessPluginTest(instance,
NPAPIClient::PluginClient::HostFunctions(), test_name);
windowless_plugin = true;
diff --git a/webkit/glue/plugins/test/plugin_windowless_test.cc b/webkit/glue/plugins/test/plugin_windowless_test.cc
index 2ab9ca1..665072e 100644
--- a/webkit/glue/plugins/test/plugin_windowless_test.cc
+++ b/webkit/glue/plugins/test/plugin_windowless_test.cc
@@ -7,6 +7,7 @@
#include "webkit/glue/plugins/test/plugin_client.h"
#if defined(OS_MACOSX)
+#include <ApplicationServices/ApplicationServices.h>
#include <Carbon/Carbon.h>
#endif
@@ -47,6 +48,15 @@ static bool IsMouseUpEvent(NPEvent* np_event) {
#endif
}
+static bool IsWindowActivationEvent(NPEvent* np_event) {
+#if defined(OS_WIN)
+ NOTIMPLEMENTED();
+ return false;
+#elif defined(OS_MACOSX)
+ return np_event->what == activateEvt;
+#endif
+}
+
int16 WindowlessPluginTest::HandleEvent(void* event) {
NPNetscapeFuncs* browser = NPAPIClient::PluginClient::HostFunctions();
@@ -86,13 +96,17 @@ int16 WindowlessPluginTest::HandleEvent(void* event) {
} else if (test_name_ == "multiple_instances_sync_calls") {
MultipleInstanceSyncCalls(browser);
}
-
+#if OS_MACOSX
+ } else if (IsWindowActivationEvent(np_event) &&
+ test_name_ == "convert_point") {
+ ConvertPoint(browser);
+#endif
} else if (IsMouseMoveEvent(np_event) &&
test_name_ == "execute_script_delete_in_mouse_move") {
ExecuteScript(browser, id(), "DeletePluginWithinScript();", NULL);
SignalTestCompleted();
} else if (IsMouseUpEvent(np_event) &&
- test_name_ == "delete_frame_test") {
+ test_name_ == "delete_frame_test") {
ExecuteScript(
browser, id(),
"parent.document.getElementById('frame').outerHTML = ''", NULL);
@@ -134,4 +148,79 @@ void WindowlessPluginTest::MultipleInstanceSyncCalls(NPNetscapeFuncs* browser) {
SignalTestCompleted();
}
+void WindowlessPluginTest::ConvertPoint(NPNetscapeFuncs* browser) {
+#if defined(OS_MACOSX)
+ // First, just sanity-test that round trips work.
+ NPCoordinateSpace spaces[] = { NPCoordinateSpacePlugin,
+ NPCoordinateSpaceWindow,
+ NPCoordinateSpaceFlippedWindow,
+ NPCoordinateSpaceScreen,
+ NPCoordinateSpaceFlippedScreen };
+ for (unsigned int i = 0; i < arraysize(spaces); ++i) {
+ for (unsigned int j = 0; j < arraysize(spaces); ++j) {
+ double x, y, round_trip_x, round_trip_y;
+ if (!(browser->convertpoint(id(), 0, 0, spaces[i], &x, &y, spaces[j])) ||
+ !(browser->convertpoint(id(), x, y, spaces[j], &round_trip_x,
+ &round_trip_y, spaces[i]))) {
+ SetError("Conversion failed");
+ SignalTestCompleted();
+ return;
+ }
+ if (i != j && x == 0 && y == 0) {
+ SetError("Converting a coordinate should change it");
+ SignalTestCompleted();
+ return;
+ }
+ if (round_trip_x != 0 || round_trip_y != 0) {
+ SetError("Round-trip conversion should give return the original point");
+ SignalTestCompleted();
+ return;
+ }
+ }
+ }
+
+ // Now, more extensive testing on a single point.
+ double screen_x, screen_y;
+ browser->convertpoint(id(), 0, 0, NPCoordinateSpacePlugin,
+ &screen_x, &screen_y, NPCoordinateSpaceScreen);
+ double flipped_screen_x, flipped_screen_y;
+ browser->convertpoint(id(), 0, 0, NPCoordinateSpacePlugin,
+ &flipped_screen_x, &flipped_screen_y,
+ NPCoordinateSpaceFlippedScreen);
+ double window_x, window_y;
+ browser->convertpoint(id(), 0, 0, NPCoordinateSpacePlugin,
+ &window_x, &window_y, NPCoordinateSpaceWindow);
+ double flipped_window_x, flipped_window_y;
+ browser->convertpoint(id(), 0, 0, NPCoordinateSpacePlugin,
+ &flipped_window_x, &flipped_window_y,
+ NPCoordinateSpaceFlippedWindow);
+
+ CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID());
+
+ // Check that all the coordinates are right. The plugin is in a 600x600 window
+ // at (100, 100), with a content area origin of (100, 100).
+ // Y-coordinates are not checked exactly so that the test is robust against
+ // toolbar changes, info bar visibility, etc.
+ if (screen_x != flipped_screen_x)
+ SetError("Flipping screen coordinates shouldn't change x");
+ else if (flipped_screen_y != main_display_bounds.size.height - screen_y)
+ SetError("Flipped screen coordinates should be flipped vertically!");
+ else if (screen_x != 200)
+ SetError("Screen x location is wrong");
+ else if (flipped_screen_y < 200 || flipped_screen_y > 400)
+ SetError("Screen y location is wrong");
+ if (window_x != flipped_window_x)
+ SetError("Flipping window coordinates shouldn't change x");
+ else if (flipped_window_y != 600 - window_y)
+ SetError("Flipped window coordinates should be flipped vertically!");
+ else if (window_x != 100)
+ SetError("Window x location is wrong");
+ else if (flipped_screen_y < 100 || flipped_screen_y > 300)
+ SetError("Window y location is wrong");
+#else
+ SetError("Unimplemented");
+#endif
+ SignalTestCompleted();
+}
+
} // namespace NPAPIClient
diff --git a/webkit/glue/plugins/test/plugin_windowless_test.h b/webkit/glue/plugins/test/plugin_windowless_test.h
index 5135c4c..7ca13af 100644
--- a/webkit/glue/plugins/test/plugin_windowless_test.h
+++ b/webkit/glue/plugins/test/plugin_windowless_test.h
@@ -24,6 +24,7 @@ class WindowlessPluginTest : public PluginTest {
const std::string& script, NPVariant* result);
void ExecuteScriptDeleteInPaint(NPNetscapeFuncs* browser);
void MultipleInstanceSyncCalls(NPNetscapeFuncs* browser);
+ void ConvertPoint(NPNetscapeFuncs* browser);
private:
std::string test_name_;
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index 7978964..940a2a6 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -355,11 +355,8 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
void UpdateIdleEventRate();
#endif // !NP_NO_CARBON
- // Note: the following coordinates are all in screen coordinates, relative an
- // upper-left (0,0).
- // The frame of the window containing this plugin.
- gfx::Rect containing_window_frame_;
- // The upper-left corner of the web content area.
+ // The upper-left corner of the web content area in screen coordinates,
+ // relative to an upper-left (0,0).
gfx::Point content_area_origin_;
// True if the plugin thinks it has keyboard focus
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
index 2955ec5..8c9d3d2 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
+++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm
@@ -586,7 +586,7 @@ void WebPluginDelegateImpl::SetContainerVisibility(bool is_visible) {
void WebPluginDelegateImpl::WindowFrameChanged(gfx::Rect window_frame,
gfx::Rect view_frame) {
- containing_window_frame_ = window_frame;
+ instance()->set_window_frame(window_frame);
SetContentAreaOrigin(gfx::Point(view_frame.x(), view_frame.y()));
}