| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/test/plugin/plugin_windowed_test.h" |
| |
| #include "base/logging.h" |
| #include "content/test/plugin/plugin_client.h" |
| |
| namespace NPAPIClient { |
| |
| WindowedPluginTest::WindowedPluginTest(NPP id, NPNetscapeFuncs *host_functions) |
| : PluginTest(id, host_functions), |
| window_(NULL), done_(false) { |
| } |
| |
| WindowedPluginTest::~WindowedPluginTest() { |
| if (window_) |
| DestroyWindow(window_); |
| } |
| |
| NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) { |
| if (pNPWindow->window == NULL) |
| return NPERR_NO_ERROR; |
| |
| if (test_name() == "create_instance_in_paint" && test_id() == "2") { |
| SignalTestCompleted(); |
| return NPERR_NO_ERROR; |
| } |
| |
| if (window_) |
| return NPERR_NO_ERROR; |
| |
| HWND parent = reinterpret_cast<HWND>(pNPWindow->window); |
| if (!::IsWindow(parent)) { |
| SetError("Invalid arguments passed in"); |
| return NPERR_INVALID_PARAM; |
| } |
| |
| if ((test_name() == "create_instance_in_paint" && test_id() == "1") || |
| test_name() == "alert_in_window_message" || |
| test_name() == "set_title_in_paint" || |
| test_name() == "set_title_in_set_window_and_paint") { |
| static ATOM window_class = 0; |
| if (!window_class) { |
| WNDCLASSEX wcex; |
| wcex.cbSize = sizeof(WNDCLASSEX); |
| wcex.style = CS_DBLCLKS; |
| wcex.lpfnWndProc = &NPAPIClient::WindowedPluginTest::WindowProc; |
| wcex.cbClsExtra = 0; |
| wcex.cbWndExtra = 0; |
| wcex.hInstance = GetModuleHandle(NULL); |
| wcex.hIcon = 0; |
| wcex.hCursor = 0; |
| wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1); |
| wcex.lpszMenuName = 0; |
| wcex.lpszClassName = L"CreateInstanceInPaintTestWindowClass"; |
| wcex.hIconSm = 0; |
| window_class = RegisterClassEx(&wcex); |
| } |
| |
| window_ = CreateWindowEx( |
| WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, |
| MAKEINTATOM(window_class), 0, |
| WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE , |
| 0, 0, 100, 100, parent, 0, GetModuleHandle(NULL), 0); |
| DCHECK(window_); |
| // TODO: this propery leaks. |
| ::SetProp(window_, L"Plugin_Instance", this); |
| } |
| |
| if (test_name() == "set_title_in_set_window_and_paint") |
| CallJSFunction(this, "PluginCreated"); |
| |
| return NPERR_NO_ERROR; |
| } |
| |
| NPError WindowedPluginTest::Destroy() { |
| if (test_name() != "ensure_scripting_works_in_destroy") |
| return NPERR_NO_ERROR; |
| |
| // Bug 23706: ensure that scripting works with no asserts. |
| NPObject *window_obj = NULL; |
| HostFunctions()->getvalue(id(), NPNVWindowNPObject,&window_obj); |
| |
| if (!window_obj) { |
| SetError("Failed to get NPObject for plugin instance"); |
| } else { |
| std::string script = "javascript:GetMagicNumber()"; |
| NPString script_string; |
| script_string.UTF8Characters = script.c_str(); |
| script_string.UTF8Length = |
| static_cast<unsigned int>(script.length()); |
| |
| NPVariant result_var; |
| bool result = HostFunctions()->evaluate( |
| id(), window_obj, &script_string, &result_var); |
| if (!result || |
| result_var.type != NPVariantType_Double || |
| result_var.value.doubleValue != 42.0) { |
| SetError("Failed to script during NPP_Destroy"); |
| } |
| } |
| |
| SignalTestCompleted(); |
| return NPERR_NO_ERROR; |
| } |
| |
| void WindowedPluginTest::CallJSFunction( |
| WindowedPluginTest* this_ptr, const char* function) { |
| NPIdentifier function_id = this_ptr->HostFunctions()->getstringidentifier( |
| function); |
| |
| NPObject *window_obj = NULL; |
| this_ptr->HostFunctions()->getvalue( |
| this_ptr->id(), NPNVWindowNPObject, &window_obj); |
| |
| NPVariant rv; |
| this_ptr->HostFunctions()->invoke( |
| this_ptr->id(), window_obj, function_id, NULL, 0, &rv); |
| } |
| |
| LRESULT CALLBACK WindowedPluginTest::WindowProc( |
| HWND window, UINT message, WPARAM wparam, LPARAM lparam) { |
| WindowedPluginTest* this_ptr = |
| reinterpret_cast<WindowedPluginTest*> |
| (::GetProp(window, L"Plugin_Instance")); |
| |
| if (message == WM_PAINT) { |
| PAINTSTRUCT ps; |
| HDC hdc = BeginPaint(window, &ps); |
| HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0)); |
| HGDIOBJ orig = SelectObject(hdc, brush); |
| RECT r; |
| GetClientRect(window, &r); |
| Rectangle(hdc, 0, 0, r.right, r.bottom); |
| SelectObject(hdc, orig); // restore |
| DeleteObject(brush); |
| EndPaint(window, &ps); |
| } |
| |
| if (this_ptr && !this_ptr->done_) { |
| if (this_ptr->test_name() == "create_instance_in_paint" && |
| message == WM_PAINT) { |
| this_ptr->done_ = true; |
| CallJSFunction(this_ptr, "CreateNewInstance"); |
| } else if (this_ptr->test_name() == "alert_in_window_message" && |
| message == WM_PAINT) { |
| this_ptr->done_ = true; |
| // We call this function twice as we want to display two alerts |
| // and verify that we don't hang the browser. |
| CallJSFunction(this_ptr, "CallAlert"); |
| CallJSFunction(this_ptr, "CallAlert"); |
| } else if (this_ptr->test_name() == "set_title_in_paint" && |
| message == WM_PAINT) { |
| this_ptr->done_ = true; |
| CallJSFunction(this_ptr, "SetTitle"); |
| } else if (this_ptr->test_name() == "set_title_in_set_window_and_paint" && |
| message == WM_PAINT) { |
| this_ptr->done_ = true; |
| CallJSFunction(this_ptr, "PluginShown"); |
| } |
| |
| if (this_ptr->done_) { |
| ::RemoveProp(window, L"Plugin_Instance"); |
| } |
| } |
| |
| return DefWindowProc(window, message, wparam, lparam); |
| } |
| |
| } // namespace NPAPIClient |