diff --git a/tests/cefclient/cefclient.cpp b/tests/cefclient/cefclient.cpp index 72d33566f..b9328d3ac 100644 --- a/tests/cefclient/cefclient.cpp +++ b/tests/cefclient/cefclient.cpp @@ -11,6 +11,7 @@ #include "resource_util.h" #include "scheme_test.h" #include "string_util.h" +#include "uiplugin_test.h" #include @@ -56,6 +57,9 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, // Register the internal client plugin. InitPluginTest(); + // Register the internal UI client plugin. + InitUIPluginTest(); + // Register the V8 extension handler. InitExtensionTest(); @@ -341,6 +345,9 @@ public: std::wstring& mimeType, int loadFlags) { + DWORD dwSize; + LPBYTE pBytes; + std::wstring url = request->GetURL(); if(url == L"http://tests/request") { // Show the request contents @@ -349,15 +356,27 @@ public: resourceStream = CefStreamReader::CreateForData( (void*)dump.c_str(), dump.size() * sizeof(wchar_t)); mimeType = L"text/plain"; - } else if(wcsstr(url.c_str(), L"logo.gif") != NULL) { + } else if(url == L"http://tests/uiapp") { + // Show the uiapp contents + if(LoadBinaryResource(IDS_UIPLUGIN, dwSize, pBytes)) { + resourceStream = CefStreamReader::CreateForHandler( + new ClientReadHandler(pBytes, dwSize)); + mimeType = L"text/html"; + } + } else if(wcsstr(url.c_str(), L"/logo.gif") != NULL) { // Any time we find "logo.gif" in the URL substitute in our own image - DWORD dwSize; - LPBYTE pBytes; if(LoadBinaryResource(IDS_LOGO, dwSize, pBytes)) { resourceStream = CefStreamReader::CreateForHandler( new ClientReadHandler(pBytes, dwSize)); mimeType = L"image/jpg"; } + } else if(wcsstr(url.c_str(), L"/logoball.png") != NULL) { + // Load the "logoball.png" image resource. + if(LoadBinaryResource(IDS_LOGOBALL, dwSize, pBytes)) { + resourceStream = CefStreamReader::CreateForHandler( + new ClientReadHandler(pBytes, dwSize)); + mimeType = L"image/png"; + } } return RV_CONTINUE; } @@ -485,6 +504,9 @@ public: { // Add the V8 bindings. InitBindingTest(browser, frame, object); + + // Add the UI app V8 bindings. + InitUIBindingTest(browser, frame, object); return RV_HANDLED; } @@ -515,6 +537,7 @@ public: m_MainHwnd = hwnd; Unlock(); } + HWND GetMainHwnd() { return m_MainHwnd; } void SetEditHwnd(HWND hwnd) { @@ -554,6 +577,23 @@ protected: bool m_bCanGoForward; }; +// global handler instance +CefRefPtr g_handler; + +CefRefPtr AppGetBrowser() +{ + if(!g_handler.get()) + return NULL; + return g_handler->GetBrowser(); +} + +HWND AppGetMainHwnd() +{ + if(!g_handler.get()) + return NULL; + return g_handler->GetMainHwnd(); +} + // // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) @@ -562,7 +602,6 @@ protected: // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - static CefRefPtr handler; static HWND backWnd = NULL, forwardWnd = NULL, reloadWnd = NULL, stopWnd = NULL, editWnd = NULL; static WNDPROC editWndOldProc = NULL; @@ -577,10 +616,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_CHAR: - if (wParam == VK_RETURN && handler.get()) + if (wParam == VK_RETURN && g_handler.get()) { // When the user hits the enter key load the URL - CefRefPtr browser = handler->GetBrowser(); + CefRefPtr browser = g_handler->GetBrowser(); wchar_t strPtr[MAX_URL_LENGTH] = {0}; *((LPWORD)strPtr) = MAX_URL_LENGTH; LRESULT strLen = SendMessage(hWnd, EM_GETLINE, 0, (LPARAM)strPtr); @@ -603,8 +642,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CREATE: { // Create the single static handler class instance - handler = new ClientHandler(); - handler->SetMainHwnd(hWnd); + g_handler = new ClientHandler(); + g_handler->SetMainHwnd(hWnd); // Create the child windows used for navigation RECT rect; @@ -650,7 +689,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) reinterpret_cast(GetWindowLongPtr(editWnd, GWLP_WNDPROC)); SetWindowLongPtr(editWnd, GWLP_WNDPROC, reinterpret_cast(WndProc)); - handler->SetEditHwnd(editWnd); + g_handler->SetEditHwnd(editWnd); rect.top += URLBAR_HEIGHT; @@ -661,7 +700,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // Creat the new child child browser window CefBrowser::CreateBrowser(info, false, - static_cast>(handler), + static_cast>(g_handler), L"http://www.google.com"); // Start the timer that will be used to update child window state @@ -670,11 +709,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; case WM_TIMER: - if(handler.get() && handler->GetBrowserHwnd()) + if(g_handler.get() && g_handler->GetBrowserHwnd()) { // Retrieve the current navigation state bool isLoading, canGoBack, canGoForward; - handler->GetNavState(isLoading, canGoBack, canGoForward); + g_handler->GetNavState(isLoading, canGoBack, canGoForward); // Update the status of child windows EnableWindow(editWnd, TRUE); @@ -688,8 +727,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: { CefRefPtr browser; - if(handler.get()) - browser = handler->GetBrowser(); + if(g_handler.get()) + browser = g_handler->GetBrowser(); wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); @@ -779,6 +818,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if(browser.get()) RunSchemeTest(browser); return 0; + case ID_TESTS_UIAPP: // Test the UI app + if(browser.get()) + RunUIPluginTest(browser); + return 0; } } break; @@ -789,15 +832,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; case WM_SETFOCUS: - if(handler.get() && handler->GetBrowserHwnd()) + if(g_handler.get() && g_handler->GetBrowserHwnd()) { // Pass focus to the browser window - PostMessage(handler->GetBrowserHwnd(), WM_SETFOCUS, wParam, NULL); + PostMessage(g_handler->GetBrowserHwnd(), WM_SETFOCUS, wParam, NULL); } return 0; case WM_SIZE: - if(handler.get() && handler->GetBrowserHwnd()) + if(g_handler.get() && g_handler->GetBrowserHwnd()) { // Resize the browser window and address bar to match the new frame // window size @@ -810,7 +853,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) HDWP hdwp = BeginDeferWindowPos(1); hdwp = DeferWindowPos(hdwp, editWnd, NULL, urloffset, 0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, handler->GetBrowserHwnd(), NULL, + hdwp = DeferWindowPos(hdwp, g_handler->GetBrowserHwnd(), NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); EndDeferWindowPos(hdwp); @@ -818,7 +861,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_ERASEBKGND: - if(handler.get() && handler->GetBrowserHwnd()) + if(g_handler.get() && g_handler->GetBrowserHwnd()) { // Dont erase the background if the browser window has been loaded // (this avoids flashing) diff --git a/tests/cefclient/cefclient.h b/tests/cefclient/cefclient.h index 2b538cb52..1895bc200 100644 --- a/tests/cefclient/cefclient.h +++ b/tests/cefclient/cefclient.h @@ -5,3 +5,10 @@ #pragma once #include "resource.h" +#include "cef.h" + +// Return the main browser window instance. +CefRefPtr AppGetBrowser(); + +// Return the main application window handle. +HWND AppGetMainHwnd(); diff --git a/tests/cefclient/cefclient.rc b/tests/cefclient/cefclient.rc index 3655dfb2e..42ef620d2 100644 --- a/tests/cefclient/cefclient.rc +++ b/tests/cefclient/cefclient.rc @@ -29,6 +29,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // IDS_LOGO BINARY "res\logo.jpg" +IDS_UIPLUGIN BINARY "res\uiplugin.html" +IDS_LOGOBALL BINARY "res\logoball.png" ///////////////////////////////////////////////////////////////////////////// // @@ -64,6 +66,7 @@ BEGIN MENUITEM "Popup Window", ID_TESTS_POPUP MENUITEM "Request", ID_TESTS_REQUEST MENUITEM "Scheme Handler", ID_TESTS_SCHEME_HANDLER + MENUITEM "UI App Example", ID_TESTS_UIAPP END END diff --git a/tests/cefclient/cefclient.vcproj b/tests/cefclient/cefclient.vcproj index ed6fde850..e54700fb9 100644 --- a/tests/cefclient/cefclient.vcproj +++ b/tests/cefclient/cefclient.vcproj @@ -265,6 +265,22 @@ RelativePath=".\string_util.h" > + + + + + + + + diff --git a/tests/cefclient/cefclient.vsprops b/tests/cefclient/cefclient.vsprops index 77cfb5ac9..366681a54 100644 --- a/tests/cefclient/cefclient.vsprops +++ b/tests/cefclient/cefclient.vsprops @@ -12,7 +12,7 @@ /> (instance->pdata); @@ -33,6 +34,7 @@ NPError NPP_Destroy(NPP instance, NPSavedData** save) { return NPERR_NO_ERROR; } +static NPError NPP_SetWindow(NPP instance, NPWindow* window_info) { if (instance == NULL) return NPERR_INVALID_INSTANCE_ERROR; diff --git a/tests/cefclient/res/logoball.png b/tests/cefclient/res/logoball.png new file mode 100644 index 000000000..ef115ca07 Binary files /dev/null and b/tests/cefclient/res/logoball.png differ diff --git a/tests/cefclient/res/uiplugin.html b/tests/cefclient/res/uiplugin.html new file mode 100644 index 000000000..3af8c4c7f --- /dev/null +++ b/tests/cefclient/res/uiplugin.html @@ -0,0 +1,57 @@ + + +User Interface App Example + + +
+ + + + +
+ + + + + + + + + + + + + + +
User Interface App Example
An embedded OpenGL plugin window that communicates with the Chromium browser control via JavaScript calls. + View Page Source
You can make the square rotate! +
    +
  • Click the square with the left mouse button or click the Decrement Rotation button to decrement the rotation value.
  • +
  • Click the square with the right mouse button or click the Increment Rotation button to increment the rotation value.
  • +
  • Click the Reset Rotation button to reset the rotation value to zero.
  • +
+
+ +
+ +
+ +
+ Rotation Value: +
+ + +
+
+
+ + + diff --git a/tests/cefclient/resource.h b/tests/cefclient/resource.h index 44dad4cd6..0e8fc8fb4 100644 --- a/tests/cefclient/resource.h +++ b/tests/cefclient/resource.h @@ -28,8 +28,11 @@ #define ID_TESTS_POPUP 32775 #define ID_TESTS_REQUEST 32776 #define ID_TESTS_SCHEME_HANDLER 32777 +#define ID_TESTS_UIAPP 32778 #define IDC_STATIC -1 #define IDS_LOGO 1000 +#define IDS_UIPLUGIN 1001 +#define IDS_LOGOBALL 1002 // Next default values for new objects // diff --git a/tests/cefclient/uiplugin.cpp b/tests/cefclient/uiplugin.cpp new file mode 100644 index 000000000..721db7142 --- /dev/null +++ b/tests/cefclient/uiplugin.cpp @@ -0,0 +1,284 @@ +// Copyright (c) 2009 The Chromium Embedded Framework Authors. +// Portions copyright (c) 2006-2008 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 "stdafx.h" +#include "uiplugin.h" +#include "cefclient.h" +#include +#include + + +// Initialized in NP_Initialize. +NPNetscapeFuncs* g_uibrowser = NULL; + +// Global values. +float g_rotationspeed = 0.0f; +float g_theta = 0.0f; + +// Class holding pointers for the client plugin window. +class ClientPlugin +{ +public: + ClientPlugin() + { + hWnd = NULL; + hDC = NULL; + hRC = NULL; + } + + HWND hWnd; + HDC hDC; + HGLRC hRC; +}; + +// Forward declarations of functions included in this code module: +LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, + LPARAM lParam); +void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC); +void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC); + +static +NPError NPP_New(NPMIMEType plugin_type, NPP instance, uint16 mode, int16 argc, + char* argn[], char* argv[], NPSavedData* saved) { + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + ClientPlugin *plugin = new ClientPlugin; + instance->pdata = reinterpret_cast(plugin); + + return NPERR_NO_ERROR; +} + +static +NPError NPP_Destroy(NPP instance, NPSavedData** save) { + ClientPlugin *plugin = reinterpret_cast(instance->pdata); + + if (plugin) { + if(plugin->hWnd) { + DestroyWindow(plugin->hWnd); + DisableOpenGL(plugin->hWnd, plugin->hDC, plugin->hRC); + } + delete plugin; + g_rotationspeed = 0.0f; + g_theta = 0.0f; + } + + return NPERR_NO_ERROR; +} + +static +NPError NPP_SetWindow(NPP instance, NPWindow* window_info) { + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + if (window_info == NULL) + return NPERR_GENERIC_ERROR; + + ClientPlugin *plugin = reinterpret_cast(instance->pdata); + HWND parent_hwnd = reinterpret_cast(window_info->window); + + if (plugin->hWnd == NULL) + { + WNDCLASS wc; + HINSTANCE hInstance = GetModuleHandle(NULL); + + // Register the window class. + wc.style = CS_OWNDC; + wc.lpfnWndProc = PluginWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = L"ClientUIPlugin"; + RegisterClass(&wc); + + // Create the main window. + plugin->hWnd = CreateWindow(L"ClientUIPlugin", L"Client UI Plugin", + WS_CHILD, 0, 0, 0, 0, parent_hwnd, NULL, hInstance, NULL); + + // Enable OpenGL drawing for the window. + EnableOpenGL(plugin->hWnd, &(plugin->hDC), &(plugin->hRC)); + } + + // Position the window and make sure it's visible. + RECT parent_rect; + GetClientRect(parent_hwnd, &parent_rect); + SetWindowPos(plugin->hWnd, NULL, parent_rect.left, parent_rect.top, + parent_rect.right - parent_rect.left, + parent_rect.bottom - parent_rect.top, SWP_SHOWWINDOW); + + UpdateWindow(plugin->hWnd); + ShowWindow(plugin->hWnd, SW_SHOW); + + return NPERR_NO_ERROR; +} + +NPError API_CALL NP_UIGetEntryPoints(NPPluginFuncs* pFuncs) +{ + pFuncs->newp = NPP_New; + pFuncs->destroy = NPP_Destroy; + pFuncs->setwindow = NPP_SetWindow; + return NPERR_NO_ERROR; +} + +NPError API_CALL NP_UIInitialize(NPNetscapeFuncs* pFuncs) +{ + g_uibrowser = pFuncs; + return NPERR_NO_ERROR; +} + +NPError API_CALL NP_UIShutdown(void) +{ + g_uibrowser = NULL; + return NPERR_NO_ERROR; +} + +// Send the notification to the browser as a JavaScript function call. +static void NotifyNewRotation(float value) +{ + std::wstringstream buf; + buf << L"notifyNewRotation(" << value << L");"; + AppGetBrowser()->GetMainFrame()->ExecuteJavaScript(buf.str(), std::wstring(), + 0); +} + +void ModifyRotation(float value) +{ + g_rotationspeed += value; + NotifyNewRotation(g_rotationspeed); +} + +void ResetRotation() +{ + g_rotationspeed = 0.0; + NotifyNewRotation(g_rotationspeed); +} + +// Nice little fly polygon borrowed from the OpenGL Red Book. +const GLubyte fly[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, + 0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, + 0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, + 0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, + 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, + 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, + 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, + 0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, + 0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, + 0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, + 0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, + 0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, + 0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, + 0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, + 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08}; + + +// Plugin window procedure. +LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, + LPARAM lParam) +{ + HDC hDC; + int width, height; + + switch(message) + { + case WM_CREATE: + // Start the timer that's used for redrawing. + SetTimer(hWnd, 1, 1, NULL); + return 0; + + case WM_DESTROY: + // Stop the timer that's used for redrawing. + KillTimer(hWnd, 1); + return 0; + + case WM_LBUTTONDOWN: + // Decrement rotation speed. + ModifyRotation(-2.0f); + return 0; + + case WM_RBUTTONDOWN: + // Increment rotation speed. + ModifyRotation(2.0f); + return 0; + + case WM_SIZE: + // Resize the OpenGL viewport to match the window size. + width = LOWORD(lParam); + height = HIWORD(lParam); + glViewport(0, 0, width, height); + break; + + case WM_ERASEBKGND: + return 0; + + case WM_TIMER: + // Adjust the theta value and redraw the display when the timer fires. + hDC = GetDC(hWnd); + + glClearColor(1.0f, 1.0f, 1.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(fly); + + glRotatef(g_theta, 0.0f, 0.0f, 1.0f); + glBegin(GL_QUADS); + glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.7f, 0.7f); + glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(0.7f, -0.7f); + glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(-0.7f, -0.7f); + glColor3f(1.0f, 0.0f, 1.0f); glVertex2f(-0.7f, 0.7f); + glEnd(); + + glDisable(GL_POLYGON_STIPPLE); + glPopMatrix(); + + SwapBuffers(hDC); + ReleaseDC(hWnd, hDC); + + g_theta -= g_rotationspeed; + } + + return DefWindowProc(hWnd, message, wParam, lParam); +} + +// Enable OpenGL. +void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC) +{ + PIXELFORMATDESCRIPTOR pfd; + int format; + + // Get the device context. + *hDC = GetDC(hWnd); + + // Set the pixel format for the DC. + ZeroMemory(&pfd, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 16; + pfd.iLayerType = PFD_MAIN_PLANE; + format = ChoosePixelFormat(*hDC, &pfd); + SetPixelFormat(*hDC, format, &pfd); + + // Create and enable the render contex. + *hRC = wglCreateContext(*hDC); + wglMakeCurrent(*hDC, *hRC); +} + +// Disable OpenGL. +void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC) +{ + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hRC); + ReleaseDC(hWnd, hDC); +} diff --git a/tests/cefclient/uiplugin.h b/tests/cefclient/uiplugin.h new file mode 100644 index 000000000..b2063db81 --- /dev/null +++ b/tests/cefclient/uiplugin.h @@ -0,0 +1,22 @@ +// Copyright (c) 2009 The Chromium Embedded Framework Authors. +// Portions copyright (c) 2006-2008 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. + +// Portions of this implementation are borrowed from webkit\default_plugin\ +// plugin_impl.h + +#pragma once + +#include "cef_nplugin.h" + +extern NPNetscapeFuncs* g_uibrowser; + +NPError API_CALL NP_UIGetEntryPoints(NPPluginFuncs* pFuncs); +NPError API_CALL NP_UIInitialize(NPNetscapeFuncs* pFuncs); +NPError API_CALL NP_UIShutdown(void); + +// Function called to modify the rotation value. +void ModifyRotation(float value); +// Function called to reset the rotation value. +void ResetRotation(); \ No newline at end of file diff --git a/tests/cefclient/uiplugin_test.cpp b/tests/cefclient/uiplugin_test.cpp new file mode 100644 index 000000000..610e02859 --- /dev/null +++ b/tests/cefclient/uiplugin_test.cpp @@ -0,0 +1,109 @@ +// Copyright (c) 2008-2009 The Chromium Embedded Framework 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 "stdafx.h" +#include "uiplugin_test.h" +#include "uiplugin.h" +#include "cefclient.h" + + +void InitUIPluginTest() +{ + // Structure providing information about the client plugin. + CefPluginInfo plugin_info; + plugin_info.display_name = L"Client UI Plugin"; + plugin_info.unique_name = L"client_ui_plugin"; + plugin_info.version = L"1, 0, 0, 1"; + plugin_info.description = L"My Example Client UI Plugin"; + + CefPluginMimeType mime_type; + mime_type.mime_type = L"application/x-client-ui-plugin"; + mime_type.file_extensions.push_back(L"*"); + plugin_info.mime_types.push_back(mime_type); + + plugin_info.np_getentrypoints = NP_UIGetEntryPoints; + plugin_info.np_initialize = NP_UIInitialize; + plugin_info.np_shutdown = NP_UIShutdown; + + // Register the internal client plugin + CefRegisterPlugin(plugin_info); +} + +// Implementation of the V8 handler class for the "window.uiapp" functions. +class ClientV8UIHandler : public CefThreadSafeBase +{ +public: + ClientV8UIHandler() {} + + // Execute with the specified argument list and return value. Return true if + // the method was handled. + virtual bool Execute(const std::wstring& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + std::wstring& exception) + { + if(name == L"modifyRotation") { + // This function requires one argument. + if(arguments.size() != 1) + return false; + + float increment = 0.; + if(arguments[0]->IsInt()) { + // The argument is an integer value. + increment = static_cast(arguments[0]->GetIntValue()); + } else if(arguments[0]->IsDouble()) { + // The argument is an double value. + increment = static_cast(arguments[0]->GetDoubleValue()); + } + + if(increment != 0.) { + // Modify the rotation accordingly. + ModifyRotation(increment); + return true; + } + } else if(name == L"resetRotation") { + // Reset the rotation value. + ResetRotation(); + return true; + } else if(name == L"viewSource") { + // View the page source. + AppGetBrowser()->GetMainFrame()->ViewSource(); + return true; + } + + return false; + } +}; + +void InitUIBindingTest(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object) +{ + if(frame->GetURL().find(L"http://tests/uiapp") != 0) + return; + + // Create the new V8 object. + CefRefPtr testObjPtr = CefV8Value::CreateObject(NULL); + // Add the new V8 object to the global window object with the name "uiapp". + object->SetValue(L"uiapp", testObjPtr); + + // Create an instance of ClientV8UIHandler as the V8 handler. + CefRefPtr handlerPtr = new ClientV8UIHandler(); + + // Add a new V8 function to the uiapp object with the name "modifyRotation". + testObjPtr->SetValue(L"modifyRotation", + CefV8Value::CreateFunction(L"modifyRotation", handlerPtr)); + // Add a new V8 function to the uiapp object with the name "resetRotation". + testObjPtr->SetValue(L"resetRotation", + CefV8Value::CreateFunction(L"resetRotation", handlerPtr)); + // Add a new V8 function to the uiapp object with the name "viewSource". + testObjPtr->SetValue(L"viewSource", + CefV8Value::CreateFunction(L"viewSource", handlerPtr)); +} + +void RunUIPluginTest(CefRefPtr browser) +{ + browser->GetMainFrame()->LoadURL(L"http://tests/uiapp"); +} diff --git a/tests/cefclient/uiplugin_test.h b/tests/cefclient/uiplugin_test.h new file mode 100644 index 000000000..2cbabd8e0 --- /dev/null +++ b/tests/cefclient/uiplugin_test.h @@ -0,0 +1,18 @@ +// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#pragma once +#include "cef.h" + +// Register the internal client plugin. +void InitUIPluginTest(); + +// Add the V8 bindings. +void InitUIBindingTest(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object); + + +// Run the test. +void RunUIPluginTest(CefRefPtr browser);