diff options
-rw-r--r-- | chrome/test/data/npapi/convert_point.html | 27 | ||||
-rw-r--r-- | chrome/test/ui/npapi_uitest.cc | 21 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_instance.cc | 36 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_instance.h | 9 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_client.cc | 3 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_windowless_test.cc | 93 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_windowless_test.h | 1 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 7 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 2 |
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())); } |