cefclient:
- Add the User Interface App Example that demonstrates two-way JavaScript communication between the page and an embedded plugin implemented using OpenGL. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@40 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
2b7e69d200
commit
d7c54d6514
|
@ -11,6 +11,7 @@
|
|||
#include "resource_util.h"
|
||||
#include "scheme_test.h"
|
||||
#include "string_util.h"
|
||||
#include "uiplugin_test.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
|
@ -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<ClientHandler> g_handler;
|
||||
|
||||
CefRefPtr<CefBrowser> 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<ClientHandler> 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<CefBrowser> browser = handler->GetBrowser();
|
||||
CefRefPtr<CefBrowser> 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<WNDPROC>(GetWindowLongPtr(editWnd, GWLP_WNDPROC));
|
||||
SetWindowLongPtr(editWnd, GWLP_WNDPROC,
|
||||
reinterpret_cast<LONG_PTR>(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<CefRefPtr<CefHandler>>(handler),
|
||||
static_cast<CefRefPtr<CefHandler>>(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<CefBrowser> 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)
|
||||
|
|
|
@ -5,3 +5,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "resource.h"
|
||||
#include "cef.h"
|
||||
|
||||
// Return the main browser window instance.
|
||||
CefRefPtr<CefBrowser> AppGetBrowser();
|
||||
|
||||
// Return the main application window handle.
|
||||
HWND AppGetMainHwnd();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -265,6 +265,22 @@
|
|||
RelativePath=".\string_util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\uiplugin.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\uiplugin.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\uiplugin_test.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\uiplugin_test.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib shlwapi.lib rpcrt4.lib winmm.lib"
|
||||
AdditionalDependencies="comctl32.lib shlwapi.lib rpcrt4.lib winmm.lib opengl32.lib glu32.lib"
|
||||
AdditionalLibraryDirectories=""$(OutDir)""
|
||||
/>
|
||||
<Tool
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// Initialized in NP_Initialize.
|
||||
NPNetscapeFuncs* g_browser = NULL;
|
||||
|
||||
|
||||
static
|
||||
NPError NPP_New(NPMIMEType plugin_type, NPP instance, uint16 mode, int16 argc,
|
||||
char* argn[], char* argv[], NPSavedData* saved) {
|
||||
if (instance == NULL)
|
||||
|
@ -22,6 +22,7 @@ NPError NPP_New(NPMIMEType plugin_type, NPP instance, uint16 mode, int16 argc,
|
|||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
static
|
||||
NPError NPP_Destroy(NPP instance, NPSavedData** save) {
|
||||
ClientPlugin* plugin_impl = reinterpret_cast<ClientPlugin*>(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;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
|
@ -0,0 +1,57 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>User Interface App Example</title>
|
||||
</head>
|
||||
<body bottommargin="2" rightmargin="0" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" style="font-family: Verdana, Arial;">
|
||||
<div align="center">
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="99.9%" height="100%">
|
||||
<tr>
|
||||
<td height="100%" align="center" valign="top">
|
||||
<table border="0" cellpadding="2" cellspacing="0">
|
||||
<tr>
|
||||
<td colspan="2" style="font-size: 18pt;">User Interface App Example</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="font-size: 8pt;"><i>An embedded OpenGL plugin window that communicates with the Chromium browser control via JavaScript calls.</i>
|
||||
<a href="#" onclick="window.uiapp.viewSource(); return false;">View Page Source</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" height="10"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100" valign="top"><img src="logoball.png" width="100" height="101"></td>
|
||||
<td style="font-size: 10pt;"><span style="font-size: 12pt;">You can make the square rotate!</span>
|
||||
<ul>
|
||||
<li>Click the square with the left mouse button or click the <b>Decrement Rotation</b> button to decrement the rotation value.</li>
|
||||
<li>Click the square with the right mouse button or click the <b>Increment Rotation</b> button to increment the rotation value.</li>
|
||||
<li>Click the <b>Reset Rotation</b> button to reset the rotation value to zero.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div style="padding: 2px; margin: 5px; border: red 1px solid; width: 350px;">
|
||||
<embed type="application/x-client-ui-plugin" width=350 height=350></embed>
|
||||
</div>
|
||||
|
||||
<form name="control">
|
||||
Rotation Value: <input type="text" name="rotation_field" value="0" size="5" readonly>
|
||||
<br/><input type="button" value="Decrement Rotation" onclick="window.uiapp.modifyRotation(-2.0);">
|
||||
<input type="button" value="Increment Rotation" onclick="window.uiapp.modifyRotation(2.0);">
|
||||
<input type="button" value="Reset Rotation" name="reset_button" onclick="window.uiapp.resetRotation();" disabled>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<script language="JavaScript">
|
||||
// Called by the application after rotation has been changed.
|
||||
// |val| is the new rotation value.
|
||||
function notifyNewRotation(val)
|
||||
{
|
||||
document.control.rotation_field.value = val;
|
||||
document.control.reset_button.disabled = (val == 0);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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 <gl/gl.h>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
// 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<void*>(plugin);
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
static
|
||||
NPError NPP_Destroy(NPP instance, NPSavedData** save) {
|
||||
ClientPlugin *plugin = reinterpret_cast<ClientPlugin*>(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<ClientPlugin*>(instance->pdata);
|
||||
HWND parent_hwnd = reinterpret_cast<HWND>(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);
|
||||
}
|
|
@ -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();
|
|
@ -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<CefV8Handler>
|
||||
{
|
||||
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<CefV8Value> object,
|
||||
const CefV8ValueList& arguments,
|
||||
CefRefPtr<CefV8Value>& 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<float>(arguments[0]->GetIntValue());
|
||||
} else if(arguments[0]->IsDouble()) {
|
||||
// The argument is an double value.
|
||||
increment = static_cast<float>(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<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefV8Value> object)
|
||||
{
|
||||
if(frame->GetURL().find(L"http://tests/uiapp") != 0)
|
||||
return;
|
||||
|
||||
// Create the new V8 object.
|
||||
CefRefPtr<CefV8Value> 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<CefV8Handler> 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<CefBrowser> browser)
|
||||
{
|
||||
browser->GetMainFrame()->LoadURL(L"http://tests/uiapp");
|
||||
}
|
|
@ -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<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefV8Value> object);
|
||||
|
||||
|
||||
// Run the test.
|
||||
void RunUIPluginTest(CefRefPtr<CefBrowser> browser);
|
Loading…
Reference in New Issue