Initial commit of libcef and cefclient projects.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2008-12-02 15:48:14 +00:00
parent 11f5769f19
commit 9c58b671a8
71 changed files with 12808 additions and 0 deletions

5
AUTHORS.txt Normal file
View File

@ -0,0 +1,5 @@
# This file is an addendum to the Chromium AUTHORS file.
# Names should be added to this file like so:
# Name or Organization <email address>
Marshall Greenblatt <magreenblatt@gmail.com>

View File

@ -0,0 +1,10 @@
The Chromium Embedded Framework (CEF) project is built on top of the Chromium
project source tree. Because of the Chromium project's constant state of flux
certain revisions of the CEF project may not be compatible with all Chromium
revisions, and visa-versa. This document tracks the combination of CEF
revision and Chromium revision that have been officially tested by the CEF
development team.
Date | CEF Revision | Chromium Revision
-------------------------------------------------------------------------------
2008-12-02 | /trunk@2 | /trunk@6213

29
LICENSE.txt Normal file
View File

@ -0,0 +1,29 @@
// Copyright (c) 2008 Marshall A. Greenblatt. Portions Copyright (c)
// 2006-2008 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

751
cef.sln Normal file
View File

@ -0,0 +1,751 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebKit (readonly)", "WebKit (readonly)", "{1088577A-0C49-4DE0-85CD-B68AD0BE55AA}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebCore", "..\webkit\build\WebCore\WebCore.vcproj", "{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{2E2D3301-2EC4-4C0F-B889-87073B30F673} = {2E2D3301-2EC4-4C0F-B889-87073B30F673}
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9} = {6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203} = {2F7EDFA2-EE27-4D83-8454-9EFBD5779203}
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B} = {4BD929D4-494B-4EE8-91F6-FD0277A51D2B}
{31D88CBF-DC28-47A8-8838-BF81D528EE74} = {31D88CBF-DC28-47A8-8838-BF81D528EE74}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Port", "..\webkit\build\port\port.vcproj", "{5597AD47-3494-4750-A235-4F9C2F864700}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203} = {2F7EDFA2-EE27-4D83-8454-9EFBD5779203}
{2E2D3301-2EC4-4C0F-B889-87073B30F673} = {2E2D3301-2EC4-4C0F-B889-87073B30F673}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Glue", "..\webkit\build\glue\glue.vcproj", "{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{2E2D3301-2EC4-4C0F-B889-87073B30F673} = {2E2D3301-2EC4-4C0F-B889-87073B30F673}
{60B43839-95E6-4526-A661-209F16335E0E} = {60B43839-95E6-4526-A661-209F16335E0E}
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6} = {1C16337B-ACF3-4D03-AA90-851C5B5EADA6}
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203} = {2F7EDFA2-EE27-4D83-8454-9EFBD5779203}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "skia", "..\skia\skia.vcproj", "{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTF", "..\webkit\build\JavaScriptCore\WTF.vcproj", "{AA8A5A85-592B-4357-BC60-E0E91E026AF6}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite", "..\third_party\sqlite\sqlite.vcproj", "{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebKit (ours)", "WebKit (ours)", "{CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icu", "..\third_party\icu38\build\icu.vcproj", "{8C27D792-2648-4F5E-9ED0-374276327308}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{A0D94973-D355-47A5-A1E2-3456F321F010} = {A0D94973-D355-47A5-A1E2-3456F321F010}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "icu", "icu", "{1AFC1EC3-24FA-4260-B099-76319EC9977A}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\third_party\libpng\libpng.vcproj", "{C564F145-9172-42C3-BFCB-6014CA97DBCD}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\third_party\zlib\zlib.vcproj", "{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "..\third_party\libjpeg\libjpeg.vcproj", "{238CE175-76CE-4A25-A676-69D115885601}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Breakpad", "Breakpad", "{873D095E-150E-4262-8C41-2D8ED02F0F57}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "breakpad_handler", "..\breakpad\breakpad_handler.vcproj", "{B55CA863-B374-4BAF-95AC-539E4FA4C90C}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml", "..\third_party\libxml\build\libxml.vcproj", "{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{31D88CBF-DC28-47A8-8838-BF81D528EE74} = {31D88CBF-DC28-47A8-8838-BF81D528EE74}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxslt", "..\third_party\libxslt\build\libxslt.vcproj", "{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7} = {F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B} = {4BD929D4-494B-4EE8-91F6-FD0277A51D2B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "V8Bindings", "..\webkit\build\V8Bindings\V8Bindings.vcproj", "{625A8F11-2B4E-45B4-BD99-C6D629C606C0}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{2E2D3301-2EC4-4C0F-B889-87073B30F673} = {2E2D3301-2EC4-4C0F-B889-87073B30F673}
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203} = {2F7EDFA2-EE27-4D83-8454-9EFBD5779203}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "..\third_party\bzip2\bzip2.vcproj", "{2A70CBF0-847E-4E3A-B926-542A656DC7FE}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcef", "libcef\libcef.vcproj", "{FA39524D-3067-4141-888D-28A86C66F2B9}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED} = {FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0} = {F54ABC59-5C00-414A-A9BA-BAF26D1699F0}
{F4F4BCAA-EA59-445C-A119-3E6C29647A51} = {F4F4BCAA-EA59-445C-A119-3E6C29647A51}
{EF5E94AB-B646-4E5B-A058-52EF07B8351C} = {EF5E94AB-B646-4E5B-A058-52EF07B8351C}
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09} = {C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {C564F145-9172-42C3-BFCB-6014CA97DBCD}
{C0334F9A-1168-4101-9DD8-C30FB252D435} = {C0334F9A-1168-4101-9DD8-C30FB252D435}
{B55CA863-B374-4BAF-95AC-539E4FA4C90C} = {B55CA863-B374-4BAF-95AC-539E4FA4C90C}
{AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
{A508ADD3-CECE-4E0F-8448-2F5E454DF551} = {A508ADD3-CECE-4E0F-8448-2F5E454DF551}
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C} = {8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}
{7100F41F-868D-4E99-80A2-AF8E6574749D} = {7100F41F-868D-4E99-80A2-AF8E6574749D}
{625A8F11-2B4E-45B4-BD99-C6D629C606C0} = {625A8F11-2B4E-45B4-BD99-C6D629C606C0}
{5916D37D-8C97-424F-A904-74E52594C2D6} = {5916D37D-8C97-424F-A904-74E52594C2D6}
{5597AD47-3494-4750-A235-4F9C2F864700} = {5597AD47-3494-4750-A235-4F9C2F864700}
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934} = {49909552-0B0C-4C14-8CF6-DB8A2ADE0934}
{326E9795-E760-410A-B69A-3F79DB3F5243} = {326E9795-E760-410A-B69A-3F79DB3F5243}
{2A70CBF0-847E-4E3A-B926-542A656DC7FE} = {2A70CBF0-847E-4E3A-B926-542A656DC7FE}
{238CE175-76CE-4A25-A676-69D115885601} = {238CE175-76CE-4A25-A676-69D115885601}
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6} = {1C16337B-ACF3-4D03-AA90-851C5B5EADA6}
{1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "V8", "V8", "{B353A6A5-9551-4B76-908E-0F0A9B31E4CE}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "googleurl", "..\googleurl\build\googleurl.vcproj", "{EF5E94AB-B646-4E5B-A058-52EF07B8351C}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "modp_b64", "..\third_party\modp_b64\modp_b64.vcproj", "{7100F41F-868D-4E99-80A2-AF8E6574749D}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "activex_shim", "..\webkit\activex_shim\activex_shim.vcproj", "{F4F4BCAA-EA59-445C-A119-3E6C29647A51}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{EF5E94AB-B646-4E5B-A058-52EF07B8351C} = {EF5E94AB-B646-4E5B-A058-52EF07B8351C}
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "..\net\build\net.vcproj", "{326E9795-E760-410A-B69A-3F79DB3F5243}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41} = {E13045CD-7E1F-4A41-9B18-8D288B2E7B41}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "..\base\build\base.vcproj", "{1832A374-8A74-4F9E-B536-69A699B3E165}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_gfx", "..\base\build\base_gfx.vcproj", "{A508ADD3-CECE-4E0F-8448-2F5E454DF551}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libxml projects", "libxml projects", "{032541FB-1E7C-4423-B657-4A71FE180C8A}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml_config", "..\third_party\libxml\build\libxml_config.vcproj", "{31D88CBF-DC28-47A8-8838-BF81D528EE74}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libxslt projects", "libxslt projects", "{BC732CFC-DE0A-4CF5-B8AA-3269C2F6D399}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxslt_config", "..\third_party\libxslt\build\libxslt_config.vcproj", "{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "default_plugin", "..\webkit\default_plugin\default_plugin.vcproj", "{5916D37D-8C97-424F-A904-74E52594C2D6}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{31D88CBF-DC28-47A8-8838-BF81D528EE74} = {31D88CBF-DC28-47A8-8838-BF81D528EE74}
{60B43839-95E6-4526-A661-209F16335E0E} = {60B43839-95E6-4526-A661-209F16335E0E}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JavaScriptCore_pcre", "..\webkit\build\JavaScriptCore\JavaScriptCore_pcre.vcproj", "{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "V8Bindings_prebuild", "..\webkit\build\V8Bindings\V8Bindings_prebuild.vcproj", "{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_snapshot", "..\v8\tools\visual_studio\v8_snapshot.vcproj", "{C0334F9A-1168-4101-9DD8-C30FB252D435}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{865575D0-37E2-405E-8CBA-5F6C485B5A26} = {865575D0-37E2-405E-8CBA-5F6C485B5A26}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdch", "..\sdch\sdch.vcproj", "{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cef", "Cef", "{08BAF606-555E-4048-A47E-22CFA89A21B4}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{A507014E-5F1D-4A60-963B-518FCED4B8AD}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tld_cleanup", "..\net\build\tld_cleanup.vcproj", "{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165}
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
{EF5E94AB-B646-4E5B-A058-52EF07B8351C} = {EF5E94AB-B646-4E5B-A058-52EF07B8351C}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_mksnapshot", "..\v8\tools\visual_studio\v8_mksnapshot.vcproj", "{865575D0-37E2-405E-8CBA-5F6C485B5A26}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{21E22961-22BF-4493-BD3A-868F93DA5179} = {21E22961-22BF-4493-BD3A-868F93DA5179}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8", "..\v8\tools\visual_studio\v8.vcproj", "{21E22961-22BF-4493-BD3A-868F93DA5179}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{EC8B7909-62AF-470D-A75D-E1D89C837142} = {EC8B7909-62AF-470D-A75D-E1D89C837142}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_base", "..\v8\tools\visual_studio\v8_base.vcproj", "{EC8B7909-62AF-470D-A75D-E1D89C837142}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "V8Config", "..\webkit\build\JSConfig\V8Config.vcproj", "{2E2D3301-2EC4-4C0F-B889-87073B30F673}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "localized_strings", "..\webkit\build\localized_strings\localized_strings.vcproj", "{60B43839-95E6-4526-A661-209F16335E0E}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cefclient", "tests\cefclient\cefclient.vcproj", "{6617FED9-C5D4-4907-BF55-A90062A6683F}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{EC8B7909-62AF-470D-A75D-E1D89C837142} = {EC8B7909-62AF-470D-A75D-E1D89C837142}
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C} = {8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}
{625A8F11-2B4E-45B4-BD99-C6D629C606C0} = {625A8F11-2B4E-45B4-BD99-C6D629C606C0}
{7100F41F-868D-4E99-80A2-AF8E6574749D} = {7100F41F-868D-4E99-80A2-AF8E6574749D}
{60B43839-95E6-4526-A661-209F16335E0E} = {60B43839-95E6-4526-A661-209F16335E0E}
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {C564F145-9172-42C3-BFCB-6014CA97DBCD}
{5597AD47-3494-4750-A235-4F9C2F864700} = {5597AD47-3494-4750-A235-4F9C2F864700}
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9} = {6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}
{FA39524D-3067-4141-888D-28A86C66F2B9} = {FA39524D-3067-4141-888D-28A86C66F2B9}
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0} = {F54ABC59-5C00-414A-A9BA-BAF26D1699F0}
{21E22961-22BF-4493-BD3A-868F93DA5179} = {21E22961-22BF-4493-BD3A-868F93DA5179}
{B55CA863-B374-4BAF-95AC-539E4FA4C90C} = {B55CA863-B374-4BAF-95AC-539E4FA4C90C}
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09} = {C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
{1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165}
{238CE175-76CE-4A25-A676-69D115885601} = {238CE175-76CE-4A25-A676-69D115885601}
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6} = {1C16337B-ACF3-4D03-AA90-851C5B5EADA6}
{5916D37D-8C97-424F-A904-74E52594C2D6} = {5916D37D-8C97-424F-A904-74E52594C2D6}
{AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {AA8A5A85-592B-4357-BC60-E0E91E026AF6}
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
{326E9795-E760-410A-B69A-3F79DB3F5243} = {326E9795-E760-410A-B69A-3F79DB3F5243}
{C0334F9A-1168-4101-9DD8-C30FB252D435} = {C0334F9A-1168-4101-9DD8-C30FB252D435}
{F4F4BCAA-EA59-445C-A119-3E6C29647A51} = {F4F4BCAA-EA59-445C-A119-3E6C29647A51}
{EF5E94AB-B646-4E5B-A058-52EF07B8351C} = {EF5E94AB-B646-4E5B-A058-52EF07B8351C}
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED} = {FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}
{A508ADD3-CECE-4E0F-8448-2F5E454DF551} = {A508ADD3-CECE-4E0F-8448-2F5E454DF551}
{2A70CBF0-847E-4E3A-B926-542A656DC7FE} = {2A70CBF0-847E-4E3A-B926-542A656DC7FE}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icudt", "..\third_party\icu38\build\icudt.vcproj", "{A0D94973-D355-47A5-A1E2-3456F321F010}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Debug|Win32.ActiveCfg = Debug|Win32
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Debug|Win32.Build.0 = Debug|Win32
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Release|Mixed Platforms.Build.0 = Release|Win32
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Release|Win32.ActiveCfg = Release|Win32
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6}.Release|Win32.Build.0 = Release|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Debug|Win32.ActiveCfg = Debug|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Debug|Win32.Build.0 = Debug|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Release|Mixed Platforms.Build.0 = Release|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Release|Win32.ActiveCfg = Release|Win32
{5597AD47-3494-4750-A235-4F9C2F864700}.Release|Win32.Build.0 = Release|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Debug|Win32.ActiveCfg = Debug|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Debug|Win32.Build.0 = Debug|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Release|Mixed Platforms.Build.0 = Release|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Release|Win32.ActiveCfg = Release|Win32
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}.Release|Win32.Build.0 = Release|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Win32.ActiveCfg = Debug|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Win32.Build.0 = Debug|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Mixed Platforms.Build.0 = Release|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Win32.ActiveCfg = Release|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Win32.Build.0 = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.ActiveCfg = Debug|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Debug|Win32.Build.0 = Debug|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Mixed Platforms.Build.0 = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.ActiveCfg = Release|Win32
{AA8A5A85-592B-4357-BC60-E0E91E026AF6}.Release|Win32.Build.0 = Release|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Debug|Win32.ActiveCfg = Debug|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Debug|Win32.Build.0 = Debug|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Release|Mixed Platforms.Build.0 = Release|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Release|Win32.ActiveCfg = Release|Win32
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9}.Release|Win32.Build.0 = Release|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Debug|Win32.ActiveCfg = Debug|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Debug|Win32.Build.0 = Debug|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Release|Mixed Platforms.Build.0 = Release|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Release|Win32.ActiveCfg = Release|Win32
{8C27D792-2648-4F5E-9ED0-374276327308}.Release|Win32.Build.0 = Release|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Debug|Win32.ActiveCfg = Debug|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Debug|Win32.Build.0 = Debug|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Mixed Platforms.Build.0 = Release|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Win32.ActiveCfg = Release|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Win32.Build.0 = Release|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Debug|Win32.ActiveCfg = Debug|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Debug|Win32.Build.0 = Debug|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Release|Mixed Platforms.Build.0 = Release|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Release|Win32.ActiveCfg = Release|Win32
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}.Release|Win32.Build.0 = Release|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Debug|Win32.ActiveCfg = Debug|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Debug|Win32.Build.0 = Debug|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Release|Mixed Platforms.Build.0 = Release|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Release|Win32.ActiveCfg = Release|Win32
{238CE175-76CE-4A25-A676-69D115885601}.Release|Win32.Build.0 = Release|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Debug|Win32.ActiveCfg = Debug|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Debug|Win32.Build.0 = Debug|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Release|Mixed Platforms.Build.0 = Release|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Release|Win32.ActiveCfg = Release|Win32
{B55CA863-B374-4BAF-95AC-539E4FA4C90C}.Release|Win32.Build.0 = Release|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Debug|Win32.ActiveCfg = Debug|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Debug|Win32.Build.0 = Debug|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Release|Mixed Platforms.Build.0 = Release|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Release|Win32.ActiveCfg = Release|Win32
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7}.Release|Win32.Build.0 = Release|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Debug|Win32.ActiveCfg = Debug|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Debug|Win32.Build.0 = Debug|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Release|Mixed Platforms.Build.0 = Release|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Release|Win32.ActiveCfg = Release|Win32
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED}.Release|Win32.Build.0 = Release|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Debug|Win32.ActiveCfg = Debug|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Debug|Win32.Build.0 = Debug|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Release|Mixed Platforms.Build.0 = Release|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Release|Win32.ActiveCfg = Release|Win32
{625A8F11-2B4E-45B4-BD99-C6D629C606C0}.Release|Win32.Build.0 = Release|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Debug|Win32.ActiveCfg = Debug|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Debug|Win32.Build.0 = Debug|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Release|Mixed Platforms.Build.0 = Release|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Release|Win32.ActiveCfg = Release|Win32
{2A70CBF0-847E-4E3A-B926-542A656DC7FE}.Release|Win32.Build.0 = Release|Win32
{FA39524D-3067-4141-888D-28A86C66F2B9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{FA39524D-3067-4141-888D-28A86C66F2B9}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{FA39524D-3067-4141-888D-28A86C66F2B9}.Debug|Win32.ActiveCfg = Debug|Win32
{FA39524D-3067-4141-888D-28A86C66F2B9}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{FA39524D-3067-4141-888D-28A86C66F2B9}.Release|Mixed Platforms.Build.0 = Release|Win32
{FA39524D-3067-4141-888D-28A86C66F2B9}.Release|Win32.ActiveCfg = Release|Win32
{FA39524D-3067-4141-888D-28A86C66F2B9}.Release|Win32.Build.0 = Release|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Debug|Win32.ActiveCfg = Debug|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Debug|Win32.Build.0 = Debug|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Release|Mixed Platforms.Build.0 = Release|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Release|Win32.ActiveCfg = Release|Win32
{EF5E94AB-B646-4E5B-A058-52EF07B8351C}.Release|Win32.Build.0 = Release|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Debug|Win32.ActiveCfg = Debug|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Debug|Win32.Build.0 = Debug|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Release|Mixed Platforms.Build.0 = Release|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Release|Win32.ActiveCfg = Release|Win32
{7100F41F-868D-4E99-80A2-AF8E6574749D}.Release|Win32.Build.0 = Release|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Debug|Win32.ActiveCfg = Debug|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Debug|Win32.Build.0 = Debug|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Release|Mixed Platforms.Build.0 = Release|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Release|Win32.ActiveCfg = Release|Win32
{F4F4BCAA-EA59-445C-A119-3E6C29647A51}.Release|Win32.Build.0 = Release|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Debug|Win32.ActiveCfg = Debug|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Debug|Win32.Build.0 = Debug|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Release|Mixed Platforms.Build.0 = Release|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Release|Win32.ActiveCfg = Release|Win32
{326E9795-E760-410A-B69A-3F79DB3F5243}.Release|Win32.Build.0 = Release|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Win32.ActiveCfg = Debug|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Debug|Win32.Build.0 = Debug|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Mixed Platforms.Build.0 = Release|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Win32.ActiveCfg = Release|Win32
{1832A374-8A74-4F9E-B536-69A699B3E165}.Release|Win32.Build.0 = Release|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Debug|Win32.ActiveCfg = Debug|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Debug|Win32.Build.0 = Debug|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Release|Mixed Platforms.Build.0 = Release|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Release|Win32.ActiveCfg = Release|Win32
{A508ADD3-CECE-4E0F-8448-2F5E454DF551}.Release|Win32.Build.0 = Release|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Debug|Win32.ActiveCfg = Debug|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Debug|Win32.Build.0 = Debug|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Release|Mixed Platforms.Build.0 = Release|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Release|Win32.ActiveCfg = Release|Win32
{31D88CBF-DC28-47A8-8838-BF81D528EE74}.Release|Win32.Build.0 = Release|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Debug|Win32.ActiveCfg = Debug|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Debug|Win32.Build.0 = Debug|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Release|Mixed Platforms.Build.0 = Release|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Release|Win32.ActiveCfg = Release|Win32
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B}.Release|Win32.Build.0 = Release|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Debug|Win32.ActiveCfg = Debug|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Debug|Win32.Build.0 = Debug|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Release|Mixed Platforms.Build.0 = Release|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Release|Win32.ActiveCfg = Release|Win32
{5916D37D-8C97-424F-A904-74E52594C2D6}.Release|Win32.Build.0 = Release|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Debug|Win32.ActiveCfg = Debug|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Debug|Win32.Build.0 = Debug|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Release|Mixed Platforms.Build.0 = Release|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Release|Win32.ActiveCfg = Release|Win32
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934}.Release|Win32.Build.0 = Release|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Debug|Win32.ActiveCfg = Debug|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Debug|Win32.Build.0 = Debug|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Release|Mixed Platforms.Build.0 = Release|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Release|Win32.ActiveCfg = Release|Win32
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203}.Release|Win32.Build.0 = Release|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Debug|Win32.ActiveCfg = Debug|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Debug|Win32.Build.0 = Debug|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Release|Mixed Platforms.Build.0 = Release|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Release|Win32.ActiveCfg = Release|Win32
{C0334F9A-1168-4101-9DD8-C30FB252D435}.Release|Win32.Build.0 = Release|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Debug|Win32.ActiveCfg = Debug|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Debug|Win32.Build.0 = Debug|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Release|Mixed Platforms.Build.0 = Release|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Release|Win32.ActiveCfg = Release|Win32
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0}.Release|Win32.Build.0 = Release|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Debug|Win32.ActiveCfg = Debug|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Debug|Win32.Build.0 = Debug|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Release|Mixed Platforms.Build.0 = Release|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Release|Win32.ActiveCfg = Release|Win32
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41}.Release|Win32.Build.0 = Release|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Debug|Win32.ActiveCfg = Debug|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Debug|Win32.Build.0 = Debug|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Release|Mixed Platforms.Build.0 = Release|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Release|Win32.ActiveCfg = Release|Win32
{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Release|Win32.Build.0 = Release|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Debug|Win32.ActiveCfg = Debug|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Debug|Win32.Build.0 = Debug|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Release|Mixed Platforms.Build.0 = Release|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Release|Win32.ActiveCfg = Release|Win32
{21E22961-22BF-4493-BD3A-868F93DA5179}.Release|Win32.Build.0 = Release|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Debug|Win32.ActiveCfg = Debug|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Debug|Win32.Build.0 = Debug|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Release|Mixed Platforms.Build.0 = Release|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Release|Win32.ActiveCfg = Release|Win32
{EC8B7909-62AF-470D-A75D-E1D89C837142}.Release|Win32.Build.0 = Release|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Debug|Win32.ActiveCfg = Debug|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Debug|Win32.Build.0 = Debug|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Release|Mixed Platforms.Build.0 = Release|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Release|Win32.ActiveCfg = Release|Win32
{2E2D3301-2EC4-4C0F-B889-87073B30F673}.Release|Win32.Build.0 = Release|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Debug|Win32.ActiveCfg = Debug|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Debug|Win32.Build.0 = Debug|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Release|Mixed Platforms.Build.0 = Release|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Release|Win32.ActiveCfg = Release|Win32
{60B43839-95E6-4526-A661-209F16335E0E}.Release|Win32.Build.0 = Release|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Debug|Win32.ActiveCfg = Debug|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Debug|Win32.Build.0 = Debug|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Release|Mixed Platforms.Build.0 = Release|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Release|Win32.ActiveCfg = Release|Win32
{6617FED9-C5D4-4907-BF55-A90062A6683F}.Release|Win32.Build.0 = Release|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Debug|Win32.ActiveCfg = Debug|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Debug|Win32.Build.0 = Debug|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Release|Mixed Platforms.Build.0 = Release|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Release|Win32.ActiveCfg = Release|Win32
{A0D94973-D355-47A5-A1E2-3456F321F010}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1C16337B-ACF3-4D03-AA90-851C5B5EADA6} = {1088577A-0C49-4DE0-85CD-B68AD0BE55AA}
{AA8A5A85-592B-4357-BC60-E0E91E026AF6} = {1088577A-0C49-4DE0-85CD-B68AD0BE55AA}
{49909552-0B0C-4C14-8CF6-DB8A2ADE0934} = {1088577A-0C49-4DE0-85CD-B68AD0BE55AA}
{2E2D3301-2EC4-4C0F-B889-87073B30F673} = {1088577A-0C49-4DE0-85CD-B68AD0BE55AA}
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{5597AD47-3494-4750-A235-4F9C2F864700} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{625A8F11-2B4E-45B4-BD99-C6D629C606C0} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{F4F4BCAA-EA59-445C-A119-3E6C29647A51} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{5916D37D-8C97-424F-A904-74E52594C2D6} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{60B43839-95E6-4526-A661-209F16335E0E} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{6EAD4A4B-2BBC-4974-8E45-BB5C16CC2AC9} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{1AFC1EC3-24FA-4260-B099-76319EC9977A} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{238CE175-76CE-4A25-A676-69D115885601} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{873D095E-150E-4262-8C41-2D8ED02F0F57} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{032541FB-1E7C-4423-B657-4A71FE180C8A} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{BC732CFC-DE0A-4CF5-B8AA-3269C2F6D399} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{2A70CBF0-847E-4E3A-B926-542A656DC7FE} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{EF5E94AB-B646-4E5B-A058-52EF07B8351C} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{7100F41F-868D-4E99-80A2-AF8E6574749D} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{326E9795-E760-410A-B69A-3F79DB3F5243} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{1832A374-8A74-4F9E-B536-69A699B3E165} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{A508ADD3-CECE-4E0F-8448-2F5E454DF551} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{F54ABC59-5C00-414A-A9BA-BAF26D1699F0} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{8C27D792-2648-4F5E-9ED0-374276327308} = {1AFC1EC3-24FA-4260-B099-76319EC9977A}
{A0D94973-D355-47A5-A1E2-3456F321F010} = {1AFC1EC3-24FA-4260-B099-76319EC9977A}
{B55CA863-B374-4BAF-95AC-539E4FA4C90C} = {873D095E-150E-4262-8C41-2D8ED02F0F57}
{F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7} = {032541FB-1E7C-4423-B657-4A71FE180C8A}
{31D88CBF-DC28-47A8-8838-BF81D528EE74} = {032541FB-1E7C-4423-B657-4A71FE180C8A}
{FC0E1FD0-5DD7-4041-A1C9-CD3C376E4EED} = {BC732CFC-DE0A-4CF5-B8AA-3269C2F6D399}
{4BD929D4-494B-4EE8-91F6-FD0277A51D2B} = {BC732CFC-DE0A-4CF5-B8AA-3269C2F6D399}
{FA39524D-3067-4141-888D-28A86C66F2B9} = {08BAF606-555E-4048-A47E-22CFA89A21B4}
{6617FED9-C5D4-4907-BF55-A90062A6683F} = {08BAF606-555E-4048-A47E-22CFA89A21B4}
{C0334F9A-1168-4101-9DD8-C30FB252D435} = {B353A6A5-9551-4B76-908E-0F0A9B31E4CE}
{865575D0-37E2-405E-8CBA-5F6C485B5A26} = {B353A6A5-9551-4B76-908E-0F0A9B31E4CE}
{21E22961-22BF-4493-BD3A-868F93DA5179} = {B353A6A5-9551-4B76-908E-0F0A9B31E4CE}
{EC8B7909-62AF-470D-A75D-E1D89C837142} = {B353A6A5-9551-4B76-908E-0F0A9B31E4CE}
{E13045CD-7E1F-4A41-9B18-8D288B2E7B41} = {A507014E-5F1D-4A60-963B-518FCED4B8AD}
EndGlobalSection
EndGlobal

751
include/cef.h Normal file
View File

@ -0,0 +1,751 @@
// Copyright (c) 2008 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _CEF_H
#define _CEF_H
#include <string>
#include <map>
#include <vector>
#include "cef_ptr.h"
// This function should only be called once when the application is started.
// Create the thread to host the UI message loop. A return value of true
// indicates that it succeeded and false indicates that it failed.
bool CefInitialize();
// This function should only be called once before the application exits.
// Shut down the thread hosting the UI message loop and destroy any created
// windows.
void CefShutdown();
// Interface defining the the reference count implementation methods. All
// framework classes must implement the CefBase class.
class CefBase
{
public:
// The AddRef method increments the reference count for the object. It should
// be called for every new copy of a pointer to a given object. The resulting
// reference count value is returned and should be used for diagnostic/testing
// purposes only.
virtual int AddRef() =0;
// The Release method decrements the reference count for the object. If the
// reference count on the object falls to 0, then the object should free
// itself from memory. The resulting reference count value is returned and
// should be used for diagnostic/testing purposes only.
virtual int Release() =0;
};
// Bring in platform-specific definitions.
#ifdef _WIN32
#include "cef_win.h"
#endif
// Template that provides atomic implementations of AddRef() and Release()
// along with Lock() and Unlock() methods to protect critical sections of
// code from simultaneous access by multiple threads.
//
// The below example demonstrates how to use the CefThreadSafeBase template.
//
// class MyHandler : public CefThreadSafeBase<CefHandler>
// {
// std::wstring m_title;
//
// virtual RetVal HandleTitleChange(const std::wstring& title)
// {
// Lock(); // Begin protecting code
// m_title = title;
// Unlock(); // Done protecting code
// return RV_HANDLED;
// }
// ...
// }
//
template <class ClassName>
class CefThreadSafeBase : public ClassName
{
public:
CefThreadSafeBase()
{
m_dwRef = 0L;
}
~CefThreadSafeBase()
{
}
// Atomic reference increment.
int AddRef()
{
return CefAtomicIncrement(&m_dwRef);
}
// Atomic reference decrement. Delete this object when no references remain.
int Release()
{
int retval = CefAtomicDecrement(&m_dwRef);
if(retval == 0)
delete this;
return retval;
}
// Use the Lock() and Unlock() methods to protect a section of code from
// simultaneous access by multiple threads.
void Lock() { m_critsec.Lock(); }
void Unlock() { m_critsec.Unlock(); }
protected:
long m_dwRef;
CefCriticalSection m_critsec;
};
class CefHandler;
class CefRequest;
class CefStreamReader;
class CefStreamWriter;
class CefPostData;
class CefPostDataElement;
class CefJSHandler;
class CefVariant;
// Class used to represent a browser window. All methods exposed by this
// class should be thread safe.
class CefBrowser : public CefBase
{
public:
// Create a new browser window using the window parameters specified
// by |windowInfo|. All values will be copied internally and the actual
// window will be created on the UI thread. The |popup| parameter should
// be true if the new window is a popup window. This method call will not
// block.
static bool CreateBrowser(CefWindowInfo& windowInfo, bool popup,
CefRefPtr<CefHandler> handler,
const std::wstring& url);
// Returns true if the browser can navigate backwards.
virtual bool CanGoBack() =0;
// Navigate backwards.
virtual void GoBack() =0;
// Returns true if the browser can navigate forwards.
virtual bool CanGoForward() =0;
// Navigate backwards.
virtual void GoForward() =0;
// Reload the current page.
virtual void Reload() =0;
// Stop loading the page.
virtual void StopLoad() =0;
// Define frame target types. Using TF_FOCUSED will target the focused
// frame and using TF_MAIN will target the main frame.
enum TargetFrame
{
TF_FOCUSED = 0,
TF_MAIN = 1
};
// Execute undo in the target frame.
virtual void Undo(TargetFrame targetFrame) =0;
// Execute redo in the target frame.
virtual void Redo(TargetFrame targetFrame) =0;
// Execute cut in the target frame.
virtual void Cut(TargetFrame targetFrame) =0;
// Execute copy in the target frame.
virtual void Copy(TargetFrame targetFrame) =0;
// Execute paste in the target frame.
virtual void Paste(TargetFrame targetFrame) =0;
// Execute delete in the target frame.
virtual void Delete(TargetFrame targetFrame) =0;
// Execute select all in the target frame.
virtual void SelectAll(TargetFrame targetFrame) =0;
// Execute printing in the target frame. The user will be prompted with
// the print dialog appropriate to the operating system.
virtual void Print(TargetFrame targetFrame) =0;
// Save the target frame's HTML source to a temporary file and open it in
// the default text viewing application.
virtual void ViewSource(TargetFrame targetFrame) =0;
// Returns the target frame's HTML source as a string.
virtual std::wstring GetSource(TargetFrame targetFrame) =0;
// Returns the target frame's display text as a string.
virtual std::wstring GetText(TargetFrame targetFrame) =0;
// Load the request represented by the |request| object.
virtual void LoadRequest(CefRefPtr<CefRequest> request) =0;
// Convenience method for loading the specified |url| in the optional target
// |frame|.
virtual void LoadURL(const std::wstring& url, const std::wstring& frame) =0;
// Load the contents of |string| with the optional dummy target |url|.
virtual void LoadString(const std::wstring& string,
const std::wstring& url) =0;
// Load the contents of |stream| with the optional dummy target |url|.
virtual void LoadStream(CefRefPtr<CefStreamReader> stream,
const std::wstring& url) =0;
// Register a new handler tied to the specified JS object |name|. Returns
// true if the handler is registered successfully.
// A JS handler will be accessible to JavaScript as window.<classname>.
virtual bool AddJSHandler(const std::wstring& classname,
CefRefPtr<CefJSHandler> handler) =0;
// Returns true if a JS handler with the specified |name| is currently
// registered.
virtual bool HasJSHandler(const std::wstring& classname) =0;
// Returns the JS handler registered with the specified |name|.
virtual CefRefPtr<CefJSHandler> GetJSHandler(const std::wstring& classname) =0;
// Unregister the JS handler registered with the specified |name|. Returns
// true if the handler is unregistered successfully.
virtual bool RemoveJSHandler(const std::wstring& classname) =0;
// Unregister all JS handlers that are currently registered.
virtual void RemoveAllJSHandlers() =0;
// Retrieve the window handle for this browser.
virtual CefWindowHandle GetWindowHandle() =0;
// Returns true if the window is a popup window.
virtual bool IsPopup() =0;
// Returns the handler for this browser.
virtual CefRefPtr<CefHandler> GetHandler() =0;
// Return the currently loaded URL.
virtual std::wstring GetURL() =0;
};
// Interface that should be implemented to handle events generated by the
// browser window. All methods exposed by this class should be thread safe.
// Each method in the interface returns a RetVal value.
class CefHandler : public CefBase
{
public:
// Define handler return value types. Returning RV_HANDLED indicates
// that the implementation completely handled the method and that no further
// processing is required. Returning RV_CONTINUE indicates that the
// implementation did not handle the method and that the default handler
// should be called.
enum RetVal
{
RV_HANDLED = 0,
RV_CONTINUE = 1
};
// Event called before a new window is created. The |parentBrowser| parameter
// will point to the parent browser window, if any. The |popup| parameter
// will be true if the new window is a popup window. If you create the window
// yourself you should populate the window handle member of |createInfo| and
// return RV_HANDLED. Otherwise, return RV_CONTINUE and the framework will
// create the window. By default, a newly created window will recieve the
// same handler as the parent window. To change the handler for the new
// window modify the object that |handler| points to.
virtual RetVal HandleBeforeCreated(CefRefPtr<CefBrowser> parentBrowser,
CefWindowInfo& createInfo, bool popup,
CefRefPtr<CefHandler>& handler,
std::wstring& url) =0;
// Event called after a new window is created. The return value is currently
// ignored.
virtual RetVal HandleAfterCreated(CefRefPtr<CefBrowser> browser) =0;
// Event called when the address bar changes. The return value is currently
// ignored.
virtual RetVal HandleAddressChange(CefRefPtr<CefBrowser> browser,
const std::wstring& url) =0;
// Event called when the page title changes. The return value is currently
// ignored.
virtual RetVal HandleTitleChange(CefRefPtr<CefBrowser> browser,
const std::wstring& title) =0;
// Various browser navigation types supported by chrome.
enum NavType
{
NAVTYPE_LINKCLICKED = 0,
NAVTYPE_FORMSUBMITTED,
NAVTYPE_BACKFORWARD,
NAVTYPE_RELOAD,
NAVTYPE_FORMRESUBMITTED,
NAVTYPE_OTHER
};
// Event called before browser navigation. The client has an opportunity to
// modify the |request| object if desired. Return RV_HANDLED to cancel
// navigation.
virtual RetVal HandleBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
NavType navType, bool isRedirect) =0;
// Event called when the browser begins loading a page. The return value is
// currently ignored.
virtual RetVal HandleLoadStart(CefRefPtr<CefBrowser> browser) =0;
// Event called when the browser is done loading a page. This event will
// be generated irrespective of whether the request completes successfully.
// The return value is currently ignored.
virtual RetVal HandleLoadEnd(CefRefPtr<CefBrowser> browser) =0;
// Supported error code values. See net\base\net_error_list.h for complete
// descriptions of the error codes.
enum ErrorCode
{
ERR_FAILED = -2,
ERR_ABORTED = -3,
ERR_INVALID_ARGUMENT = -4,
ERR_INVALID_HANDLE = -5,
ERR_FILE_NOT_FOUND = -6,
ERR_TIMED_OUT = -7,
ERR_FILE_TOO_BIG = -8,
ERR_UNEXPECTED = -9,
ERR_ACCESS_DENIED = -10,
ERR_NOT_IMPLEMENTED = -11,
ERR_CONNECTION_CLOSED = -100,
ERR_CONNECTION_RESET = -101,
ERR_CONNECTION_REFUSED = -102,
ERR_CONNECTION_ABORTED = -103,
ERR_CONNECTION_FAILED = -104,
ERR_NAME_NOT_RESOLVED = -105,
ERR_INTERNET_DISCONNECTED = -106,
ERR_SSL_PROTOCOL_ERROR = -107,
ERR_ADDRESS_INVALID = -108,
ERR_ADDRESS_UNREACHABLE = -109,
ERR_SSL_CLIENT_AUTH_CERT_NEEDED = -110,
ERR_TUNNEL_CONNECTION_FAILED = -111,
ERR_NO_SSL_VERSIONS_ENABLED = -112,
ERR_SSL_VERSION_OR_CIPHER_MISMATCH = -113,
ERR_SSL_RENEGOTIATION_REQUESTED = -114,
ERR_CERT_COMMON_NAME_INVALID = -200,
ERR_CERT_DATE_INVALID = -201,
ERR_CERT_AUTHORITY_INVALID = -202,
ERR_CERT_CONTAINS_ERRORS = -203,
ERR_CERT_NO_REVOCATION_MECHANISM = -204,
ERR_CERT_UNABLE_TO_CHECK_REVOCATION = -205,
ERR_CERT_REVOKED = -206,
ERR_CERT_INVALID = -207,
ERR_CERT_END = -208,
ERR_INVALID_URL = -300,
ERR_DISALLOWED_URL_SCHEME = -301,
ERR_UNKNOWN_URL_SCHEME = -302,
ERR_TOO_MANY_REDIRECTS = -310,
ERR_UNSAFE_REDIRECT = -311,
ERR_UNSAFE_PORT = -312,
ERR_INVALID_RESPONSE = -320,
ERR_INVALID_CHUNKED_ENCODING = -321,
ERR_METHOD_NOT_SUPPORTED = -322,
ERR_UNEXPECTED_PROXY_AUTH = -323,
ERR_EMPTY_RESPONSE = -324,
ERR_RESPONSE_HEADERS_TOO_BIG = -325,
ERR_CACHE_MISS = -400,
ERR_INSECURE_RESPONSE = -501,
};
// Called when the browser fails to load a resource. |errorCode is the
// error code number and |failedUrl| is the URL that failed to load. To
// provide custom error text assign the text to |errorText| and return
// RV_HANDLED. Otherwise, return RV_CONTINUE for the default error text.
virtual RetVal HandleLoadError(CefRefPtr<CefBrowser> browser,
ErrorCode errorCode,
const std::wstring& failedUrl,
std::wstring& errorText) =0;
// Event called before a resource is loaded. To allow the resource to load
// normally return RV_CONTINUE. To redirect the resource to a new url
// populate the |redirectUrl| value and return RV_CONTINUE. To specify
// data for the resource return a CefStream object in |resourceStream|, set
// 'mimeType| to the resource stream's mime type, and return RV_CONTINUE.
// To cancel loading of the resource return RV_HANDLED.
virtual RetVal HandleBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
std::wstring& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
std::wstring& mimeType,
int loadFlags) =0;
// Various context menu types supported by chrome.
enum MenuType
{
MENUTYPE_NONE = 0,
MENUTYPE_PAGE,
MENUTYPE_FRAME,
MENUTYPE_LINK,
MENUTYPE_IMAGE,
MENUTYPE_IMAGE_LINK,
MENUTYPE_SELECTION,
MENUTYPE_EDITABLE
};
// Structure representing menu information
struct MenuInfo
{
MenuType menuType;
int x;
int y;
std::wstring linkUrl;
std::wstring imageUrl;
std::wstring pageUrl;
std::wstring frameUrl;
std::wstring selectionText;
std::wstring misspelledWord;
int editFlags;
std::string securityInfo;
};
// The MenuInfo editFlags value will be a combination of the following
enum MenuCapability
{
CAN_DO_NONE = 0x0,
CAN_UNDO = 0x1,
CAN_REDO = 0x2,
CAN_CUT = 0x4,
CAN_COPY = 0x8,
CAN_PASTE = 0x10,
CAN_DELETE = 0x20,
CAN_SELECT_ALL = 0x40,
CAN_GO_FORWARD = 0x80,
CAN_GO_BACK = 0x100,
};
// Event called before a context menu is displayed. To cancel display of the
// default context menu return RV_HANDLED.
virtual RetVal HandleBeforeMenu(CefRefPtr<CefBrowser> browser,
const MenuInfo& menuInfo) =0;
// Supported menu ID values
enum MenuId
{
ID_NAV_BACK = 10,
ID_NAV_FORWARD = 11,
ID_NAV_RELOAD = 12,
ID_NAV_STOP = 13,
ID_UNDO = 20,
ID_REDO = 21,
ID_CUT = 22,
ID_COPY = 23,
ID_PASTE = 24,
ID_DELETE = 25,
ID_SELECTALL = 26,
ID_PRINT = 30,
ID_VIEWSOURCE = 31,
};
// Event called to optionally override the default text for a context menu
// item. |label| contains the default text and may be modified to substitute
// alternate text. The return value is currently ignored.
virtual RetVal HandleGetMenuLabel(CefRefPtr<CefBrowser> browser,
MenuId menuId, std::wstring& label) =0;
// Event called when an option is selected from the default context menu.
// Return RV_HANDLED to cancel default handling of the action.
virtual RetVal HandleMenuAction(CefRefPtr<CefBrowser> browser,
MenuId menuId) =0;
// Event called to format print headers and footers. |printInfo| contains
// platform-specific information about the printer context. |url| is the
// URL if the currently printing page, |title| is the title of the currently
// printing page, |currentPage| is the current page number and |maxPages| is
// the total number of pages. Six default header locations are provided
// by the implementation: top left, top center, top right, bottom left,
// bottom center and bottom right. To use one of these default locations
// just assign a string to the appropriate variable. To draw the header
// and footer yourself return RV_HANDLED. Otherwise, populate the approprate
// variables and return RV_CONTINUE.
virtual RetVal HandlePrintHeaderFooter(CefRefPtr<CefBrowser> browser,
CefPrintInfo& printInfo,
const std::wstring& url,
const std::wstring& title,
int currentPage, int maxPages,
std::wstring& topLeft,
std::wstring& topCenter,
std::wstring& topRight,
std::wstring& bottomLeft,
std::wstring& bottomCenter,
std::wstring& bottomRight) =0;
// Run a JS alert message. Return RV_CONTINUE to display the default alert
// or RV_HANDLED if you displayed a custom alert.
virtual RetVal HandleJSAlert(CefRefPtr<CefBrowser> browser,
const std::wstring& message) =0;
// Run a JS confirm request. Return RV_CONTINUE to display the default alert
// or RV_HANDLED if you displayed a custom alert. If you handled the alert
// set |retval| to true if the user accepted the confirmation.
virtual RetVal HandleJSConfirm(CefRefPtr<CefBrowser> browser,
const std::wstring& message, bool& retval) =0;
// Run a JS prompt request. Return RV_CONTINUE to display the default prompt
// or RV_HANDLED if you displayed a custom prompt. If you handled the prompt
// set |retval| to true if the user accepted the prompt and request and
// |result| to the resulting value.
virtual RetVal HandleJSPrompt(CefRefPtr<CefBrowser> browser,
const std::wstring& message,
const std::wstring& default_value,
bool& retval,
std::wstring& result) =0;
};
// Class used to represent a web request.
class CefRequest : public CefBase
{
public:
typedef std::map<std::wstring, std::wstring> HeaderMap;
// Create a new CefRequest object.
static CefRefPtr<CefRequest> CreateRequest();
// Fully qualified URL to load.
virtual std::wstring GetURL() =0;
virtual void SetURL(const std::wstring& url) =0;
// Optional name of the target frame.
virtual std::wstring GetFrame() =0;
virtual void SetFrame(const std::wstring& url) =0;
// Optional request method type, defaulting to POST if post data is provided
// and GET otherwise.
virtual std::wstring GetMethod() =0;
virtual void SetMethod(const std::wstring& method) =0;
// Optional post data.
virtual CefRefPtr<CefPostData> GetPostData() =0;
virtual void SetPostData(CefRefPtr<CefPostData> postData) =0;
// Optional header values.
virtual void GetHeaderMap(HeaderMap& headerMap) =0;
virtual void SetHeaderMap(const HeaderMap& headerMap) =0;
// Set all values at one time.
virtual void Set(const std::wstring& url,
const std::wstring& frame,
const std::wstring& method,
CefRefPtr<CefPostData> postData,
const HeaderMap& headerMap) =0;
};
// Class used to represent post data for a web request.
class CefPostData : public CefBase
{
public:
typedef std::vector<CefRefPtr<CefPostDataElement> > ElementVector;
// Create a new CefPostData object.
static CefRefPtr<CefPostData> CreatePostData();
// Returns the number of existing post data elements.
virtual size_t GetElementCount() =0;
// Retrieve the post data elements.
virtual void GetElements(ElementVector& elements) =0;
// Remove the specified post data element. Returns true if the removal
// succeeds.
virtual bool RemoveElement(CefRefPtr<CefPostDataElement> element) =0;
// Add the specified post data element. Returns true if the add
// succeeds.
virtual bool AddElement(CefRefPtr<CefPostDataElement> element) =0;
// Remove all existing post data elements.
virtual void RemoveElements() =0;
};
// Class used to represent a single element in the request post data.
class CefPostDataElement : public CefBase
{
public:
// Post data elements may represent either bytes or files.
enum Type
{
TYPE_EMPTY = 0,
TYPE_BYTES,
TYPE_FILE
};
// Create a new CefPostDataElement object.
static CefRefPtr<CefPostDataElement> CreatePostDataElement();
// Remove all contents from the post data element.
virtual void SetToEmpty() =0;
// The post data element will represent a file.
virtual void SetToFile(const std::wstring& fileName) =0;
// The post data element will represent bytes. The bytes passed
// in will be copied.
virtual void SetToBytes(size_t size, const void* bytes) =0;
// Return the type of this post data element.
virtual Type GetType() =0;
// Return the file name.
virtual std::wstring GetFile() =0;
// Return the number of bytes.
virtual size_t GetBytesCount() =0;
// Read up to |size| bytes into |bytes| and return the number of bytes
// actually read.
virtual size_t GetBytes(size_t size, void *bytes) =0;
};
// Class used to read data from a stream.
class CefStreamReader : public CefBase
{
public:
static CefRefPtr<CefStreamReader> CreateForFile(const std::wstring& fileName);
static CefRefPtr<CefStreamReader> CreateForData(void *data, size_t size);
// Read raw binary data.
virtual size_t Read(void *ptr, size_t size, size_t n) =0;
// Seek to the specified offset position. |whence| may be any one of
// SEEK_CUR, SEEK_END or SEEK_SET.
virtual int Seek(long offset, int whence) =0;
// Return the current offset position.
virtual long Tell() =0;
// Return non-zero if at end of file.
virtual int Eof() =0;
};
// Class used to write data to a stream.
class CefStreamWriter : public CefBase
{
public:
// Write raw binary data.
virtual size_t Write(const void *ptr, size_t size, size_t n) =0;
// Seek to the specified offset position. |whence| may be any one of
// SEEK_CUR, SEEK_END or SEEK_SET.
virtual int Seek(long offset, int whence) =0;
// Return the current offset position.
virtual long Tell() =0;
// Flush the stream.
virtual int Flush() =0;
};
// Class for implementing external JavaScript objects.
class CefJSHandler : public CefBase
{
public:
typedef std::vector<CefRefPtr<CefVariant> > VariantVector;
// Return true if the specified method exists.
virtual bool HasMethod(CefRefPtr<CefBrowser> browser,
const std::wstring& name) =0;
// Return true if the specified property exists.
virtual bool HasProperty(CefRefPtr<CefBrowser> browser,
const std::wstring& name) =0;
// Set the property value. Return true if the property is accepted.
virtual bool SetProperty(CefRefPtr<CefBrowser> browser,
const std::wstring& name,
const CefRefPtr<CefVariant> value) =0;
// Get the property value. Return true if the value is returned.
virtual bool GetProperty(CefRefPtr<CefBrowser> browser,
const std::wstring& name,
CefRefPtr<CefVariant> value) =0;
// Execute a method with the specified argument vector and return
// value. Return true if the method was handled.
virtual bool ExecuteMethod(CefRefPtr<CefBrowser> browser,
const std::wstring& name,
const VariantVector& args,
CefRefPtr<CefVariant> retval) =0;
};
// Class that represents multiple data types as a single object.
class CefVariant : public CefBase
{
public:
enum Type
{
TYPE_NULL = 0,
TYPE_BOOL,
TYPE_INT,
TYPE_DOUBLE,
TYPE_STRING,
TYPE_BOOL_ARRAY,
TYPE_INT_ARRAY,
TYPE_DOUBLE_ARRAY,
TYPE_STRING_ARRAY
};
// Return the variant data type.
virtual Type GetType() =0;
// Assign various data types.
virtual void SetNull() =0;
virtual void SetBool(bool val) =0;
virtual void SetInt(int val) =0;
virtual void SetDouble(double val) =0;
virtual void SetString(const std::wstring& val) =0;
virtual void SetBoolArray(const std::vector<bool>& val) =0;
virtual void SetIntArray(const std::vector<int>& val) =0;
virtual void SetDoubleArray(const std::vector<double>& val) =0;
virtual void SetStringArray(const std::vector<std::wstring>& val) =0;
// Retrieve various data types.
virtual bool GetBool() =0;
virtual int GetInt() =0;
virtual double GetDouble() =0;
virtual std::wstring GetString() =0;
virtual bool GetBoolArray(std::vector<bool>& val) =0;
virtual bool GetIntArray(std::vector<int>& val) =0;
virtual bool GetDoubleArray(std::vector<double>& val) =0;
virtual bool GetStringArray(std::vector<std::wstring>& val) =0;
};
#endif // _CEF_H

193
include/cef_ptr.h Normal file
View File

@ -0,0 +1,193 @@
// Copyright (c) 2008 Marshall A. Greenblatt. Portions Copyright (c)
// 2006-2008 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _CEF_PTR_H
#define _CEF_PTR_H
// Smart pointer implementation borrowed from base/ref_counted.h
//
// A smart pointer class for reference counted objects. Use this class instead
// of calling AddRef and Release manually on a reference counted object to
// avoid common memory leaks caused by forgetting to Release an object
// reference. Sample usage:
//
// class MyFoo : public CefBase {
// ...
// };
//
// void some_function() {
// // The MyFoo object that |foo| represents starts with a single
// // reference.
// CefRefPtr<MyFoo> foo = new MyFoo();
// foo->Method(param);
// // |foo| is released when this function returns
// }
//
// void some_other_function() {
// CefRefPtr<MyFoo> foo = new MyFoo();
// ...
// foo = NULL; // explicitly releases |foo|
// ...
// if (foo)
// foo->Method(param);
// }
//
// The above examples show how CefRefPtr<T> acts like a pointer to T.
// Given two CefRefPtr<T> classes, it is also possible to exchange
// references between the two objects, like so:
//
// {
// CefRefPtr<MyFoo> a = new MyFoo();
// CefRefPtr<MyFoo> b;
//
// b.swap(a);
// // now, |b| references the MyFoo object, and |a| references NULL.
// }
//
// To make both |a| and |b| in the above example reference the same MyFoo
// object, simply use the assignment operator:
//
// {
// CefRefPtr<MyFoo> a = new MyFoo();
// CefRefPtr<MyFoo> b;
//
// b = a;
// // now, |a| and |b| each own a reference to the same MyFoo object.
// // the reference count of the underlying MyFoo object will be 2.
// }
//
// Reference counted objects can also be passed as function parameters and
// used as function return values:
//
// void some_func_with_param(CefRefPtr<MyFoo> param) {
// // A reference is added to the MyFoo object that |param| represents
// // during the scope of some_func_with_param() and released when
// // some_func_with_param() goes out of scope.
// }
//
// CefRefPtr<MyFoo> some_func_with_retval() {
// // The MyFoo object that |foox| represents starts with a single
// // reference.
// CefRefPtr<MyFoo> foox = new MyFoo();
//
// // Creating the return value adds an additional reference.
// return foox;
//
// // When some_func_with_retval() goes out of scope the original |foox|
// // reference is released.
// }
//
// void and_another_function() {
// CefRefPtr<MyFoo> foo = new MyFoo();
//
// // pass |foo| as a parameter.
// some_function(foo);
//
// CefRefPtr<MyFoo> foo2 = some_func_with_retval();
// // Now, since we kept a reference to the some_func_with_retval() return
// // value, |foo2| is the only class pointing to the MyFoo object created
// in some_func_with_retval(), and it has a reference count of 1.
//
// some_func_with_retval();
// // Now, since we didn't keep a reference to the some_func_with_retval()
// // return value, the MyFoo object created in some_func_with_retval()
// // will automatically be released.
// }
//
// And in standard containers:
//
// {
// // Create a vector that holds MyFoo objects.
// std::vector<CefRefPtr<MyFoo> > MyFooVec;
//
// // The MyFoo object that |foo| represents starts with a single
// // reference.
// CefRefPtr<MyFoo> foo = new MyFoo();
//
// // When the MyFoo object is added to |MyFooVec| the reference count
// // is increased to 2.
// MyFooVec.push_back(foo);
// }
//
template <class T>
class CefRefPtr {
public:
CefRefPtr() : ptr_(NULL) {
}
CefRefPtr(T* p) : ptr_(p) {
if (ptr_)
ptr_->AddRef();
}
CefRefPtr(const CefRefPtr<T>& r) : ptr_(r.ptr_) {
if (ptr_)
ptr_->AddRef();
}
~CefRefPtr() {
if (ptr_)
ptr_->Release();
}
T* get() const { return ptr_; }
operator T*() const { return ptr_; }
T* operator->() const { return ptr_; }
CefRefPtr<T>& operator=(T* p) {
// AddRef first so that self assignment should work
if (p)
p->AddRef();
if (ptr_ )
ptr_ ->Release();
ptr_ = p;
return *this;
}
CefRefPtr<T>& operator=(const CefRefPtr<T>& r) {
return *this = r.ptr_;
}
void swap(T** pp) {
T* p = ptr_;
ptr_ = *pp;
*pp = p;
}
void swap(CefRefPtr<T>& r) {
swap(&r.ptr_);
}
private:
T* ptr_;
};
#endif // _CEF_PTR_H

186
include/cef_win.h Normal file
View File

@ -0,0 +1,186 @@
// Copyright (c) 2008 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _CEF_WIN_H
#define _CEF_WIN_H
#ifdef _WIN32
#include <windows.h>
// Atomic increment and decrement.
#define CefAtomicIncrement(p) InterlockedIncrement(p)
#define CefAtomicDecrement(p) InterlockedDecrement(p)
// Critical section wrapper.
class CefCriticalSection
{
public:
CefCriticalSection()
{
memset(&m_sec, 0, sizeof(CRITICAL_SECTION));
InitializeCriticalSection(&m_sec);
}
~CefCriticalSection()
{
DeleteCriticalSection(&m_sec);
}
void Lock()
{
EnterCriticalSection(&m_sec);
}
void Unlock()
{
LeaveCriticalSection(&m_sec);
}
CRITICAL_SECTION m_sec;
};
// Class representing window information.
class CefWindowInfo
{
public:
CefWindowInfo()
{
m_dwExStyle = 0;
m_dwStyle = 0;
m_x = 0;
m_y = 0;
m_nWidth = 0;
m_nHeight = 0;
m_hWndParent = NULL;
m_hMenu = 0;
m_hWnd = NULL;
}
~CefWindowInfo()
{
}
CefWindowInfo(const CefWindowInfo& r)
{
*this = r;
}
CefWindowInfo& operator=(const CefWindowInfo& r)
{
m_dwExStyle = r.m_dwExStyle;
m_windowName = r.m_windowName;
m_dwStyle = r.m_dwStyle;
m_x = r.m_x;
m_y = r.m_y;
m_nWidth = r.m_nWidth;
m_nHeight = r.m_nHeight;
m_hWndParent = r.m_hWndParent;
m_hMenu = r.m_hMenu;
m_hWnd = r.m_hWnd;
m_ClientInfo = r.m_ClientInfo;
return *this;
}
void SetAsChild(HWND hWndParent, RECT windowRect)
{
m_dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
| WS_CLIPSIBLINGS | WS_TABSTOP;
m_hWndParent = hWndParent;
m_x = windowRect.left;
m_y = windowRect.top;
m_nWidth = windowRect.right - windowRect.left;
m_nHeight = windowRect.bottom - windowRect.top;
}
void SetAsPopup(HWND hWndParent, LPCTSTR windowName)
{
m_dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
m_hWndParent = hWndParent;
m_x = CW_USEDEFAULT;
m_y = CW_USEDEFAULT;
m_nWidth = CW_USEDEFAULT;
m_nHeight = CW_USEDEFAULT;
m_windowName = windowName;
}
// Standard parameters required by CreateWindowEx()
DWORD m_dwExStyle;
std::wstring m_windowName;
DWORD m_dwStyle;
int m_x;
int m_y;
int m_nWidth;
int m_nHeight;
HWND m_hWndParent;
HMENU m_hMenu;
// Handle for the new browser window.
HWND m_hWnd;
// A parameter that can be used to store client-specific information.
CefRefPtr<CefBase> m_ClientInfo;
};
// Class representing print context information.
class CefPrintInfo
{
public:
CefPrintInfo()
{
m_hDC = NULL;
m_Rect.left = m_Rect.right = m_Rect.top = m_Rect.bottom = 0;
m_Scale = 0;
}
~CefPrintInfo()
{
}
CefPrintInfo(const CefPrintInfo& r)
{
*this = r;
}
CefPrintInfo& operator=(const CefPrintInfo& r)
{
m_hDC = r.m_hDC;
m_Rect.left = r.m_Rect.left;
m_Rect.right = r.m_Rect.right;
m_Rect.top = r.m_Rect.top;
m_Rect.bottom = r.m_Rect.bottom;
m_Scale = r.m_Scale;
return *this;
}
HDC m_hDC;
RECT m_Rect;
double m_Scale;
};
// Window handle.
#define CefWindowHandle HWND
#endif // _WIN32
#endif // _CEF_WIN_H

View File

@ -0,0 +1,43 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "browser_drag_delegate.h"
#include <atltypes.h>
#include "webkit/glue/webview.h"
namespace {
void GetCursorPositions(HWND hwnd, CPoint* client, CPoint* screen) {
// GetCursorPos will fail if the input desktop isn't the current desktop.
// See http://b/1173534. (0,0) is wrong, but better than uninitialized.
if (!GetCursorPos(screen))
screen->SetPoint(0, 0);
*client = *screen;
ScreenToClient(hwnd, client);
}
} // anonymous namespace
void BrowserDragDelegate::OnDragSourceCancel() {
OnDragSourceDrop();
}
void BrowserDragDelegate::OnDragSourceDrop() {
CPoint client;
CPoint screen;
GetCursorPositions(source_hwnd_, &client, &screen);
webview_->DragSourceEndedAt(client.x, client.y, screen.x, screen.y);
}
void BrowserDragDelegate::OnDragSourceMove() {
CPoint client;
CPoint screen;
GetCursorPositions(source_hwnd_, &client, &screen);
webview_->DragSourceMovedTo(client.x, client.y, screen.x, screen.y);
}

View File

@ -0,0 +1,37 @@
// Copyright (c) 2008 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.
//
// A class that implements BaseDragSource for the test shell webview delegate.
#ifndef _BROWSER_DRAG_DELEGATE_H
#define _BROWSER_DRAG_DELEGATE_H
#include "base/base_drag_source.h"
class WebView;
class BrowserDragDelegate : public BaseDragSource {
public:
BrowserDragDelegate(HWND source_hwnd, WebView* webview)
: BaseDragSource(),
source_hwnd_(source_hwnd),
webview_(webview) { }
protected:
// BaseDragSource
virtual void OnDragSourceCancel();
virtual void OnDragSourceDrop();
virtual void OnDragSourceMove();
private:
WebView* webview_;
// A HWND for the source we are associated with, used for translating
// mouse coordinates from screen to client coordinates.
HWND source_hwnd_;
};
#endif // _BROWSER_DRAG_DELEGATE_H

View File

@ -0,0 +1,54 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "browser_drop_delegate.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/webview.h"
// BaseDropTarget methods ----------------------------------------------------
DWORD BrowserDropDelegate::OnDragEnter(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect) {
WebDropData drop_data;
WebDropData::PopulateWebDropData(data_object, &drop_data);
POINT client_pt = cursor_position;
ScreenToClient(GetHWND(), &client_pt);
bool valid = webview_->DragTargetDragEnter(drop_data, client_pt.x,
client_pt.y, cursor_position.x, cursor_position.y);
return valid ? DROPEFFECT_COPY : DROPEFFECT_NONE;
}
DWORD BrowserDropDelegate::OnDragOver(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect) {
POINT client_pt = cursor_position;
ScreenToClient(GetHWND(), &client_pt);
bool valid = webview_->DragTargetDragOver(client_pt.x,
client_pt.y, cursor_position.x, cursor_position.y);
return valid ? DROPEFFECT_COPY : DROPEFFECT_NONE;
}
void BrowserDropDelegate::OnDragLeave(IDataObject* data_object) {
webview_->DragTargetDragLeave();
}
DWORD BrowserDropDelegate::OnDrop(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect) {
POINT client_pt = cursor_position;
ScreenToClient(GetHWND(), &client_pt);
webview_->DragTargetDrop(client_pt.x, client_pt.y,
cursor_position.x, cursor_position.y);
// webkit win port always returns DROPEFFECT_NONE
return DROPEFFECT_NONE;
}

View File

@ -0,0 +1,43 @@
// Copyright (c) 2008 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.
//
// A class that implements BaseDropTarget for the test shell webview delegate.
#ifndef _BROWSER_DROP_DELEGATE_H
#define _BROWSER_DROP_DELEGATE_H
#include "base/base_drop_target.h"
class WebView;
class BrowserDropDelegate : public BaseDropTarget {
public:
BrowserDropDelegate(HWND source_hwnd, WebView* webview)
: BaseDropTarget(source_hwnd),
webview_(webview) { }
protected:
// BaseDropTarget methods
virtual DWORD OnDragEnter(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect);
virtual DWORD OnDragOver(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect);
virtual void OnDragLeave(IDataObject* data_object);
virtual DWORD OnDrop(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect);
private:
WebView* webview_;
};
#endif // _BROWSER_DROP_DELEGATE_H

482
libcef/browser_impl.cc Normal file
View File

@ -0,0 +1,482 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "context.h"
#include "browser_impl.h"
#include "request_impl.h"
#include "base/string_util.h"
#include "webkit/glue/webframe.h"
CefBrowserImpl::CefBrowserImpl(CefWindowInfo& windowInfo, bool popup,
CefRefPtr<CefHandler> handler,
const std::wstring& url)
: window_info_(windowInfo), is_popup_(popup), is_modal_(false),
handler_(handler), webviewhost_(NULL), popuphost_(NULL), url_(url)
{
delegate_ = new BrowserWebViewDelegate(this);
nav_controller_.reset(new BrowserNavigationController(this));
#if defined(OS_WIN)
webview_bitmap_size_.cx = webview_bitmap_size_.cy = 0;
webview_bitmap_ = NULL;
#endif
}
CefBrowserImpl::~CefBrowserImpl()
{
#if defined(OS_WIN)
if(webview_bitmap_ != NULL)
DeleteObject(webview_bitmap_);
#endif
}
void CefBrowserImpl::GoBack()
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction, CefHandler::ID_NAV_BACK, TF_MAIN));
}
void CefBrowserImpl::GoForward()
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_NAV_FORWARD, TF_MAIN));
}
void CefBrowserImpl::Reload()
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_NAV_RELOAD, TF_MAIN));
}
void CefBrowserImpl::StopLoad()
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_NAV_STOP, TF_MAIN));
}
void CefBrowserImpl::Undo(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_UNDO, targetFrame));
}
void CefBrowserImpl::Redo(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_REDO, targetFrame));
}
void CefBrowserImpl::Cut(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_CUT, targetFrame));
}
void CefBrowserImpl::Copy(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_COPY, targetFrame));
}
void CefBrowserImpl::Paste(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_PASTE, targetFrame));
}
void CefBrowserImpl::Delete(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_DELETE, targetFrame));
}
void CefBrowserImpl::SelectAll(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_SELECTALL, targetFrame));
}
void CefBrowserImpl::Print(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_PRINT, targetFrame));
}
void CefBrowserImpl::ViewSource(TargetFrame targetFrame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_HandleAction,
CefHandler::ID_VIEWSOURCE, targetFrame));
}
void CefBrowserImpl::LoadRequest(CefRefPtr<CefRequest> request)
{
DCHECK(request.get() != NULL);
request->AddRef();
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_LoadURLForRequestRef, request.get()));
}
void CefBrowserImpl::LoadURL(const std::wstring& url, const std::wstring& frame)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_LoadURLForFrame, url, frame));
}
void CefBrowserImpl::LoadString(const std::wstring& string,
const std::wstring& url)
{
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_LoadHTML, string, url));
}
void CefBrowserImpl::LoadStream(CefRefPtr<CefStreamReader> stream,
const std::wstring& url)
{
DCHECK(stream.get() != NULL);
stream->AddRef();
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_LoadHTMLForStreamRef, stream.get(), url));
}
bool CefBrowserImpl::AddJSHandler(const std::wstring& classname,
CefRefPtr<CefJSHandler> handler)
{
bool rv = false;
Lock();
if(!HasJSHandler(classname)) {
CefRefPtr<CefJSContainer> jscon(new CefJSContainer(this, handler));
jscontainers_.insert(std::make_pair(classname, jscon));
rv = true;
}
Unlock();
return rv;
}
bool CefBrowserImpl::HasJSHandler(const std::wstring& classname)
{
Lock();
bool rv = (jscontainers_.find(classname) != jscontainers_.end());
Unlock();
return rv;
}
CefRefPtr<CefJSHandler> CefBrowserImpl::GetJSHandler(const std::wstring& classname)
{
CefRefPtr<CefJSHandler> handler;
Lock();
JSContainerMap::const_iterator it = jscontainers_.find(classname);
if(it != jscontainers_.end())
handler = it->second->GetHandler();
Unlock();
return handler;
}
bool CefBrowserImpl::RemoveJSHandler(const std::wstring& classname)
{
bool rv = false;
Lock();
JSContainerMap::iterator it = jscontainers_.find(classname);
if(it != jscontainers_.end()) {
jscontainers_.erase(it);
rv = true;
}
Unlock();
return rv;
}
void CefBrowserImpl::RemoveAllJSHandlers()
{
Lock();
jscontainers_.clear();
Unlock();
}
bool CefBrowserImpl::IsPopup()
{
Lock();
bool popup = is_popup_;
Unlock();
return popup;
}
CefRefPtr<CefHandler> CefBrowserImpl::GetHandler()
{
return handler_;
}
std::wstring CefBrowserImpl::GetURL()
{
Lock();
std::wstring url = url_;
Unlock();
return url;
}
void CefBrowserImpl::SetURL(const std::wstring& url)
{
Lock();
url_ = url;
Unlock();
}
bool CefBrowser::CreateBrowser(CefWindowInfo& windowInfo, bool popup,
CefRefPtr<CefHandler> handler,
const std::wstring& url)
{
if(!_Context.get())
return false;
std::wstring newUrl = url;
if(handler.get())
{
// Give the handler an opportunity to modify window attributes, handler,
// or cancel the window creation.
CefHandler::RetVal rv =
handler->HandleBeforeCreated(NULL, windowInfo, popup, handler, newUrl);
if(rv == CefHandler::RV_HANDLED)
return false;
}
CefRefPtr<CefBrowserImpl> browser(
new CefBrowserImpl(windowInfo, popup, handler, newUrl));
PostTask(FROM_HERE, NewRunnableMethod(browser.get(),
&CefBrowserImpl::UIT_CreateBrowser));
return true;
}
void CefBrowserImpl::UIT_LoadURL(const std::wstring& url)
{
REQUIRE_UIT();
UIT_LoadURLForRequest(url, std::wstring(), std::wstring(), NULL,
WebRequest::HeaderMap());
}
void CefBrowserImpl::UIT_LoadURLForFrame(const std::wstring& url,
const std::wstring& frame_name)
{
REQUIRE_UIT();
UIT_LoadURLForRequest(url, frame_name, std::wstring(), NULL,
WebRequest::HeaderMap());
}
void CefBrowserImpl::UIT_LoadURLForRequestRef(CefRequest* request)
{
REQUIRE_UIT();
std::wstring url = request->GetURL();
std::wstring frame_name = request->GetFrame();
std::wstring method = request->GetMethod();
CefRequestImpl *impl = static_cast<CefRequestImpl*>(request);
scoped_refptr<net::UploadData> upload_data;
CefRefPtr<CefPostData> postdata = impl->GetPostData();
if(postdata.get())
{
upload_data = new net::UploadData();
static_cast<CefPostDataImpl*>(postdata.get())->Get(*upload_data.get());
}
WebRequest::HeaderMap headers;
impl->GetHeaderMap(headers);
UIT_LoadURLForRequest(url, frame_name, method, upload_data.get(),
headers);
request->Release();
}
void CefBrowserImpl::UIT_GoBackOrForward(int offset)
{
REQUIRE_UIT();
nav_controller_->GoToOffset(offset);
}
void CefBrowserImpl::UIT_Reload()
{
REQUIRE_UIT();
nav_controller_->Reload();
}
bool CefBrowserImpl::UIT_Navigate(const BrowserNavigationEntry& entry,
bool reload)
{
REQUIRE_UIT();
WebRequestCachePolicy cache_policy;
if (reload) {
cache_policy = WebRequestReloadIgnoringCacheData;
} else if (entry.GetPageID() != -1) {
cache_policy = WebRequestReturnCacheDataElseLoad;
} else {
cache_policy = WebRequestUseProtocolCachePolicy;
}
scoped_ptr<WebRequest> request(WebRequest::Create(entry.GetURL()));
request->SetCachePolicy(cache_policy);
// If we are reloading, then WebKit will use the state of the current page.
// Otherwise, we give it the state to navigate to.
if (!reload)
request->SetHistoryState(entry.GetContentState());
request->SetExtraData(
new BrowserExtraRequestData(entry.GetPageID()));
if(entry.GetMethod().size() > 0)
request->SetHttpMethod(WideToUTF8(entry.GetMethod()));
if(entry.GetHeaders().size() > 0)
request->SetHttpHeaders(entry.GetHeaders());
if(entry.GetUploadData())
{
if(request->GetHttpMethod() == "GET" || request->GetHttpMethod() == "HEAD")
request->SetHttpMethod("POST");
if(request->GetHttpHeaderValue("Content-Type").size() == 0) {
request->SetHttpHeaderValue(
"Content-Type", "application/x-www-form-urlencoded");
}
request->SetUploadData(*entry.GetUploadData());
}
// Get the right target frame for the entry.
WebFrame* frame = UIT_GetWebView()->GetMainFrame();
if (!entry.GetTargetFrame().empty())
frame = UIT_GetWebView()->GetFrameWithName(entry.GetTargetFrame());
// TODO(mpcomplete): should we clear the target frame, or should
// back/forward navigations maintain the target frame?
frame->LoadRequest(request.get());
// Restore focus to the main frame prior to loading new request.
// This makes sure that we don't have a focused iframe. Otherwise, that
// iframe would keep focus when the SetFocus called immediately after
// LoadRequest, thus making some tests fail (see http://b/issue?id=845337
// for more details).
UIT_GetWebView()->SetFocusedFrame(frame);
UIT_SetFocus(UIT_GetWebViewHost(), true);
return true;
}
void CefBrowserImpl::UIT_BindJSObjectsToWindow(WebFrame* frame)
{
REQUIRE_UIT();
Lock();
JSContainerMap::const_iterator it = jscontainers_.begin();
for(; it != jscontainers_.end(); ++it)
it->second->BindToJavascript(frame, it->first);
Unlock();
}
CefRefPtr<CefBrowserImpl> CefBrowserImpl::UIT_CreatePopupWindow(const std::wstring& url)
{
REQUIRE_UIT();
CefWindowInfo info;
info.SetAsPopup(UIT_GetMainWndHandle(), url.c_str());
CefRefPtr<CefHandler> handler = handler_;
std::wstring newUrl = url;
if(handler_.get())
{
// Give the handler an opportunity to modify window attributes, handler,
// or cancel the window creation.
CefHandler::RetVal rv =
handler_->HandleBeforeCreated(this, info, true, handler, newUrl);
if(rv == CefHandler::RV_HANDLED)
return NULL;
}
CefRefPtr<CefBrowserImpl> browser(
new CefBrowserImpl(info, true, handler, newUrl));
browser->UIT_CreateBrowser();
return browser;
}
void CefBrowserImpl::UIT_Show(WebView* webview,
WindowOpenDisposition disposition)
{
REQUIRE_UIT();
delegate_->Show(webview, disposition);
}
void CefBrowserImpl::UIT_HandleAction(CefHandler::MenuId menuId,
TargetFrame target)
{
REQUIRE_UIT();
WebFrame* frame;
if(target == TF_FOCUSED)
frame = UIT_GetWebView()->GetFocusedFrame();
else
frame = UIT_GetWebView()->GetMainFrame();
switch(menuId)
{
case CefHandler::ID_NAV_BACK:
UIT_GoBackOrForward(-1);
break;
case CefHandler::ID_NAV_FORWARD:
UIT_GoBackOrForward(1);
break;
case CefHandler::ID_NAV_RELOAD:
UIT_Reload();
break;
case CefHandler::ID_NAV_STOP:
UIT_GetWebView()->StopLoading();
break;
case CefHandler::ID_UNDO:
frame->Undo();
break;
case CefHandler::ID_REDO:
frame->Redo();
break;
case CefHandler::ID_CUT:
frame->Cut();
break;
case CefHandler::ID_COPY:
frame->Copy();
break;
case CefHandler::ID_PASTE:
frame->Paste();
break;
case CefHandler::ID_DELETE:
frame->Delete();
break;
case CefHandler::ID_SELECTALL:
frame->SelectAll();
break;
case CefHandler::ID_PRINT:
UIT_PrintPages(frame);
break;
case CefHandler::ID_VIEWSOURCE:
UIT_ViewDocumentString(frame);
break;
}
}

229
libcef/browser_impl.h Normal file
View File

@ -0,0 +1,229 @@
// Copyright (c) 2008 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.
#ifndef _BROWSER_IMPL_H
#define _BROWSER_IMPL_H
#include "../include/cef.h"
#include "jscontainer.h"
#include "context.h"
#include "webview_host.h"
#include "browser_webview_delegate.h"
#include "browser_navigation_controller.h"
#if defined(OS_WIN)
#include "printing/win_printing_context.h"
#endif
#include "webkit/glue/webview.h"
// Implementation of CefBrowser.
class CefBrowserImpl : public CefThreadSafeBase<CefBrowser>
{
public:
CefBrowserImpl(CefWindowInfo& windowInfo, bool popup,
CefRefPtr<CefHandler> handler, const std::wstring& url);
virtual ~CefBrowserImpl();
#if defined(OS_WIN)
static LPCTSTR GetWndClass();
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam);
#endif
// CefBrowser methods
virtual bool CanGoBack();
virtual void GoBack();
virtual bool CanGoForward();
virtual void GoForward();
virtual void Reload();
virtual void StopLoad();
virtual void Undo(TargetFrame targetFrame);
virtual void Redo(TargetFrame targetFrame);
virtual void Cut(TargetFrame targetFrame);
virtual void Copy(TargetFrame targetFrame);
virtual void Paste(TargetFrame targetFrame);
virtual void Delete(TargetFrame targetFrame);
virtual void SelectAll(TargetFrame targetFrame);
virtual void Print(TargetFrame targetFrame);
virtual void ViewSource(TargetFrame targetFrame);
virtual std::wstring GetSource(TargetFrame targetFrame);
virtual std::wstring GetText(TargetFrame targetFrame);
virtual void LoadRequest(CefRefPtr<CefRequest> request);
virtual void LoadURL(const std::wstring& url, const std::wstring& frame);
virtual void LoadString(const std::wstring& string,
const std::wstring& url);
virtual void LoadStream(CefRefPtr<CefStreamReader> stream,
const std::wstring& url);
virtual bool AddJSHandler(const std::wstring& classname,
CefRefPtr<CefJSHandler> handler);
virtual bool HasJSHandler(const std::wstring& classname);
virtual CefRefPtr<CefJSHandler> GetJSHandler(const std::wstring& classname);
virtual bool RemoveJSHandler(const std::wstring& classname);
virtual void RemoveAllJSHandlers();
virtual CefWindowHandle GetWindowHandle();
virtual bool IsPopup();
virtual CefRefPtr<CefHandler> GetHandler();
virtual std::wstring GetURL();
void SetURL(const std::wstring& url);
////////////////////////////////////////////////////////////
// ALL UIT_* METHODS MUST ONLY BE CALLED ON THE UI THREAD //
////////////////////////////////////////////////////////////
WebView* UIT_GetWebView() const {
REQUIRE_UIT();
return webviewhost_.get() ? webviewhost_->webview() : NULL;
}
WebViewHost* UIT_GetWebViewHost() const {
REQUIRE_UIT();
return webviewhost_.get();
}
HWND UIT_GetWebViewWndHandle() const {
REQUIRE_UIT();
return webviewhost_->window_handle();
}
WebWidget* UIT_GetPopup() const {
REQUIRE_UIT();
return popuphost_ ? popuphost_->webwidget() : NULL;
}
WebWidgetHost* UIT_GetPopupHost() const {
REQUIRE_UIT();
return popuphost_;
}
HWND UIT_GetPopupWndHandle() const {
REQUIRE_UIT();
return popuphost_->window_handle();
}
HWND UIT_GetMainWndHandle() const {
REQUIRE_UIT();
return window_info_.m_hWnd;
}
BrowserNavigationController* UIT_GetNavigationController() {
REQUIRE_UIT();
return nav_controller_.get();
}
// Return true to allow user editing such as entering text in form elements
bool UIT_AllowEditing() { return true; }
bool UIT_IsModal() {
REQUIRE_UIT();
return is_modal_;
}
void UIT_SetIsModal(bool val) {
REQUIRE_UIT();
is_modal_ = val;
}
void UIT_SetTitle(const std::wstring& title) {
REQUIRE_UIT();
title_ = title;
}
std::wstring UIT_GetTitle() {
REQUIRE_UIT();
return title_;
}
// UIThread functions must be executed from the UI thread.
void UIT_CreateBrowser();
void UIT_LoadURL(const std::wstring& url);
void UIT_LoadURLForFrame(const std::wstring& url,
const std::wstring& frame_name);
void UIT_LoadURLForRequest(const std::wstring& url,
const std::wstring& frame_name,
const std::wstring& method,
net::UploadData *upload_data,
const WebRequest::HeaderMap& headers);
void UIT_LoadURLForRequestRef(CefRequest* request);
void UIT_LoadHTML(const std::wstring& html,
const std::wstring& url);
void UIT_LoadHTMLForStreamRef(CefStreamReader* stream,
const std::wstring& url);
void UIT_GoBackOrForward(int offset);
void UIT_Reload();
bool UIT_Navigate(const BrowserNavigationEntry& entry, bool reload);
void UIT_SetFocus(WebWidgetHost* host, bool enable);
// Called by the WebView delegate WindowObjectCleared() method, this
// binds the C++ controller classes to window JavaScript objects.
void UIT_BindJSObjectsToWindow(WebFrame* frame);
CefRefPtr<CefBrowserImpl> UIT_CreatePopupWindow(const std::wstring& url);
WebWidget* UIT_CreatePopupWidget(WebView* webview);
void UIT_ClosePopupWidget();
void UIT_Show(WebView* webview, WindowOpenDisposition disposition);
// Handles most simple browser actions
void UIT_HandleAction(CefHandler::MenuId menuId, TargetFrame target);
// Save the document HTML to a temporary file and open in the default viewing
// application
bool UIT_ViewDocumentString(WebFrame *frame);
#if defined(OS_WIN)
void UIT_GetDocumentStringNotify(TargetFrame targetFrame,
CefStreamWriter* writer, HANDLE hEvent);
void UIT_GetDocumentTextNotify(TargetFrame targetFrame,
CefStreamWriter* writer, HANDLE hEvent);
void UIT_CanGoBackNotify(bool *retVal, HANDLE hEvent);
void UIT_CanGoForwardNotify(bool *retVal, HANDLE hEvent);
#endif
bool UIT_CanGoBack() { return !nav_controller_->IsAtStart(); }
bool UIT_CanGoForward() { return !nav_controller_->IsAtEnd(); }
// Printing support
void UIT_PrintPages(WebFrame* frame);
void UIT_PrintPage(int page_number, WebFrame* frame, int total_pages);
void UIT_SwitchFrameToDisplayMediaType(WebFrame* frame);
int UIT_SwitchFrameToPrintMediaType(WebFrame* frame);
int UIT_GetPagesCount(WebFrame* frame);
#if defined(OS_WIN)
void UIT_DisableWebView(bool val);
bool UIT_IsWebViewDisabled() { return (webview_bitmap_ != NULL); }
void UIT_CaptureWebViewBitmap(HBITMAP &bitmap, SIZE &size);
void UIT_SetWebViewBitmap(HBITMAP bitmap, SIZE size);
void UIT_GetWebViewBitmap(HBITMAP &bitmap, SIZE &size)
{
bitmap = webview_bitmap_;
size.cx = webview_bitmap_size_.cx;
size.cy = webview_bitmap_size_.cy;
}
#endif
protected:
CefWindowInfo window_info_;
bool is_popup_;
bool is_modal_;
std::wstring url_;
CefRefPtr<CefHandler> handler_;
scoped_ptr<WebViewHost> webviewhost_;
WebWidgetHost* popuphost_;
scoped_refptr<BrowserWebViewDelegate> delegate_;
scoped_ptr<BrowserNavigationController> nav_controller_;
std::wstring title_;
// Backup the view size before printing since it needs to be overriden. This
// value is set to restore the view size when printing is done.
gfx::Size printing_view_size_;
// Context object used to manage printing.
printing::PrintingContext print_context_;
typedef std::map<std::wstring, CefRefPtr<CefJSContainer> > JSContainerMap;
JSContainerMap jscontainers_;
#if defined(OS_WIN)
HBITMAP webview_bitmap_;
SIZE webview_bitmap_size_;
#endif
};
#endif // _BROWSER_IMPL_H

824
libcef/browser_impl_win.cc Normal file
View File

@ -0,0 +1,824 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "context.h"
#include "browser_impl.h"
#include "browser_webkit_glue.h"
#include "stream_impl.h"
#include "base/string_util.h"
#include "base/win_util.h"
#include "skia/ext/vector_canvas.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webkit_glue.h"
#include <shellapi.h>
#include <shlwapi.h>
#include <wininet.h>
#include <winspool.h>
#define BUFFER_SIZE 32768
LPCTSTR CefBrowserImpl::GetWndClass()
{
return L"CefBrowserWindow";
}
LRESULT CALLBACK CefBrowserImpl::WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
CefBrowserImpl* browser =
static_cast<CefBrowserImpl*>(win_util::GetWindowUserData(hwnd));
switch (message) {
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
int wmEvent = HIWORD(wParam);
}
break;
case WM_DESTROY:
{
// Remove the browser from the list maintained by the context
_Context->RemoveBrowser(browser);
}
return 0;
case WM_SIZE:
if (browser && browser->UIT_GetWebView()) {
// resize the web view window to the full size of the browser window
RECT rc;
GetClientRect(browser->UIT_GetMainWndHandle(), &rc);
MoveWindow(browser->UIT_GetWebViewWndHandle(), 0, 0, rc.right, rc.bottom,
TRUE);
if(browser->UIT_IsWebViewDisabled()) {
// recreate the capture bitmap at the correct size
HBITMAP bitmap;
SIZE size;
browser->UIT_CaptureWebViewBitmap(bitmap, size);
browser->UIT_SetWebViewBitmap(bitmap, size);
}
}
return 0;
case WM_PAINT:
if(browser->UIT_IsWebViewDisabled()) {
// when web view is disabled draw the capture bitmap
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HBITMAP bitmap;
SIZE size;
browser->UIT_GetWebViewBitmap(bitmap, size);
HDC hMemDC = CreateCompatibleDC(hdc);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, bitmap);
BitBlt(hdc, 0, 0, size.cx, size.cy, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteDC(hMemDC);
EndPaint(hwnd, &ps);
return 0;
}
break;
case WM_SETFOCUS:
if (browser && browser->UIT_GetWebView())
browser->UIT_GetWebView()->SetFocus(true);
return 0;
case WM_KILLFOCUS:
if (browser && browser->UIT_GetWebView())
browser->UIT_GetWebView()->SetFocus(false);
return 0;
case WM_ERASEBKGND:
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
CefWindowHandle CefBrowserImpl::GetWindowHandle()
{
Lock();
CefWindowHandle handle = window_info_.m_hWnd;
Unlock();
return handle;
}
std::wstring CefBrowserImpl::GetSource(TargetFrame targetFrame)
{
if(!_Context->RunningOnUIThread())
{
// We need to send the request to the UI thread and wait for the result
// Event that will be used to signal that data is available. Start
// in non-signaled mode so that the event will block.
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DCHECK(hEvent != NULL);
CefRefPtr<CefStreamWriter> stream(new CefBytesWriter(BUFFER_SIZE));
// Request the data from the UI thread
stream->AddRef();
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_GetDocumentStringNotify, targetFrame, stream.get(),
hEvent));
// Wait for the UI thread callback to tell us that the data is available
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
return UTF8ToWide(
static_cast<CefBytesWriter*>(stream.get())->GetDataString());
}
else
{
// Retrieve the frame contents directly
WebFrame* frame;
if(targetFrame == TF_FOCUSED)
frame = UIT_GetWebView()->GetFocusedFrame();
else
frame = UIT_GetWebView()->GetMainFrame();
// Retrieve the document string
return UTF8ToWide(webkit_glue::GetDocumentString(frame));
}
}
std::wstring CefBrowserImpl::GetText(TargetFrame targetFrame)
{
if(!_Context->RunningOnUIThread())
{
// We need to send the request to the UI thread and wait for the result
// Event that will be used to signal that data is available. Start
// in non-signaled mode so that the event will block.
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DCHECK(hEvent != NULL);
CefRefPtr<CefStreamWriter> stream(new CefBytesWriter(BUFFER_SIZE));
// Request the data from the UI thread
stream->AddRef();
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_GetDocumentTextNotify, targetFrame, stream.get(),
hEvent));
// Wait for the UI thread callback to tell us that the data is available
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
return UTF8ToWide(
static_cast<CefBytesWriter*>(stream.get())->GetDataString());
}
else
{
// Retrieve the frame contents directly
WebFrame* frame;
if(targetFrame == TF_FOCUSED)
frame = UIT_GetWebView()->GetFocusedFrame();
else
frame = UIT_GetWebView()->GetMainFrame();
// Retrieve the document string
return webkit_glue::DumpDocumentText(frame);
}
}
bool CefBrowserImpl::CanGoBack()
{
if(!_Context->RunningOnUIThread())
{
// We need to send the request to the UI thread and wait for the result
// Event that will be used to signal that data is available. Start
// in non-signaled mode so that the event will block.
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DCHECK(hEvent != NULL);
bool retVal = true;
// Request the data from the UI thread
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_CanGoBackNotify, &retVal, hEvent));
// Wait for the UI thread callback to tell us that the data is available
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
return retVal;
}
else
{
// Call the method directly
return UIT_CanGoBack();
}
}
bool CefBrowserImpl::CanGoForward()
{
if(!_Context->RunningOnUIThread())
{
// We need to send the request to the UI thread and wait for the result
// Event that will be used to signal that data is available. Start
// in non-signaled mode so that the event will block.
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DCHECK(hEvent != NULL);
bool retVal = true;
// Request the data from the UI thread
PostTask(FROM_HERE, NewRunnableMethod(this,
&CefBrowserImpl::UIT_CanGoForwardNotify, &retVal, hEvent));
// Wait for the UI thread callback to tell us that the data is available
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
return retVal;
}
else
{
// Call the method directly
return UIT_CanGoForward();
}
}
void CefBrowserImpl::UIT_CreateBrowser()
{
REQUIRE_UIT();
// Create the new browser window
window_info_.m_hWnd = CreateWindowEx(window_info_.m_dwExStyle, GetWndClass(),
window_info_.m_windowName.c_str(), window_info_.m_dwStyle,
window_info_.m_x, window_info_.m_y, window_info_.m_nWidth,
window_info_.m_nHeight, window_info_.m_hWndParent, window_info_.m_hMenu,
_Context->GetInstanceHandle(), NULL);
DCHECK(window_info_.m_hWnd != NULL);
// Set window user data to this object for future reference from the window
// procedure
win_util::SetWindowUserData(window_info_.m_hWnd, this);
// Add the new browser to the list maintained by the context
_Context->AddBrowser(this);
// Create the webview host object
webviewhost_.reset(
WebViewHost::Create(window_info_.m_hWnd, delegate_.get(),
*_Context->GetWebPreferences()));
UIT_GetWebView()->SetUseEditorDelegate(true);
delegate_->RegisterDragDrop();
// Size the web view window to the browser window
RECT cr;
GetClientRect(window_info_.m_hWnd, &cr);
SetWindowPos(UIT_GetWebViewWndHandle(), NULL, cr.left, cr.top, cr.right,
cr.bottom, SWP_NOZORDER | SWP_SHOWWINDOW);
if(handler_.get()) {
// Notify the handler that we're done creating the new window
handler_->HandleAfterCreated(this);
}
if(url_.size() > 0)
UIT_LoadURL(url_.c_str());
else
UIT_LoadURL(L"about:blank");
}
void CefBrowserImpl::UIT_LoadURLForRequest(const std::wstring& url,
const std::wstring& frame_name,
const std::wstring& method,
net::UploadData *upload_data,
const WebRequest::HeaderMap& headers)
{
REQUIRE_UIT();
if (url.empty())
return;
std::wstring urlString(url);
if (PathFileExists(url.c_str()) || PathIsUNC(url.c_str())) {
TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
if (SUCCEEDED(UrlCreateFromPath(url.c_str(), fileURL, &fileURLLength, 0)))
urlString.assign(fileURL);
}
nav_controller_->LoadEntry(new BrowserNavigationEntry(
-1, GURL(urlString), std::wstring(), frame_name, method, upload_data,
headers));
}
void CefBrowserImpl::UIT_LoadHTML(const std::wstring& html,
const std::wstring& url)
{
REQUIRE_UIT();
std::wstring urlString(url);
if (PathFileExists(url.c_str()) || PathIsUNC(url.c_str())) {
TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
if (SUCCEEDED(UrlCreateFromPath(url.c_str(), fileURL, &fileURLLength, 0)))
urlString.assign(fileURL);
}
UIT_GetWebView()->GetMainFrame()->LoadHTMLString(
WideToUTF8(html), GURL(urlString));
}
void CefBrowserImpl::UIT_LoadHTMLForStreamRef(CefStreamReader* stream,
const std::wstring& url)
{
REQUIRE_UIT();
std::wstring urlString(url);
if (PathFileExists(url.c_str()) || PathIsUNC(url.c_str())) {
TCHAR fileURL[INTERNET_MAX_URL_LENGTH];
DWORD fileURLLength = sizeof(fileURL)/sizeof(fileURL[0]);
if (SUCCEEDED(UrlCreateFromPath(url.c_str(), fileURL, &fileURLLength, 0)))
urlString.assign(fileURL);
}
// read all of the stream data into a std::string.
std::stringstream ss;
char buff[BUFFER_SIZE];
size_t read;
do {
read = stream->Read(buff, sizeof(char), BUFFER_SIZE-1);
if(read > 0) {
buff[read] = 0;
ss << buff;
}
}
while(read > 0);
UIT_GetWebView()->GetMainFrame()->LoadHTMLString(ss.str(), GURL(urlString));
stream->Release();
}
void CefBrowserImpl::UIT_SetFocus(WebWidgetHost* host, bool enable)
{
REQUIRE_UIT();
if (enable)
::SetFocus(host->window_handle());
else if (::GetFocus() == host->window_handle())
::SetFocus(NULL);
}
WebWidget* CefBrowserImpl::UIT_CreatePopupWidget(WebView* webview)
{
REQUIRE_UIT();
DCHECK(!popuphost_);
popuphost_ = WebWidgetHost::Create(NULL, delegate_.get());
ShowWindow(UIT_GetPopupWndHandle(), SW_SHOW);
return popuphost_->webwidget();
}
void CefBrowserImpl::UIT_ClosePopupWidget()
{
REQUIRE_UIT();
PostMessage(UIT_GetPopupWndHandle(), WM_CLOSE, 0, 0);
popuphost_ = NULL;
}
static void WriteTextToFile(const std::string& data,
const std::wstring& file_path)
{
FILE* fp;
errno_t err = _wfopen_s(&fp, file_path.c_str(), L"wt");
if (err)
return;
fwrite(data.c_str(), 1, data.size(), fp);
fclose(fp);
}
bool CefBrowserImpl::UIT_ViewDocumentString(WebFrame *frame)
{
REQUIRE_UIT();
DWORD dwRetVal;
DWORD dwBufSize = 512;
TCHAR lpPathBuffer[512];
UINT uRetVal;
TCHAR szTempName[512];
dwRetVal = GetTempPath(dwBufSize, // length of the buffer
lpPathBuffer); // buffer for path
if (dwRetVal > dwBufSize || (dwRetVal == 0))
return false;
// Create a temporary file.
uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
TEXT("src"), // temp file name prefix
0, // create unique name
szTempName); // buffer for name
if (uRetVal == 0)
return false;
size_t len = wcslen(szTempName);
wcscpy(szTempName + len - 3, L"txt");
WriteTextToFile(webkit_glue::GetDocumentString(frame), szTempName);
int errorCode = (int)ShellExecute(UIT_GetMainWndHandle(), L"open", szTempName,
NULL, NULL, SW_SHOWNORMAL);
if(errorCode <= 32)
return false;
return true;
}
void CefBrowserImpl::UIT_GetDocumentStringNotify(TargetFrame targetFrame,
CefStreamWriter* writer,
HANDLE hEvent)
{
REQUIRE_UIT();
WebFrame* frame;
if(targetFrame == TF_FOCUSED)
frame = UIT_GetWebView()->GetFocusedFrame();
else
frame = UIT_GetWebView()->GetMainFrame();
// Retrieve the document string
std::string str = webkit_glue::GetDocumentString(frame);
// Write the document string to the stream
writer->Write(str.c_str(), str.size(), 1);
// Notify the calling thread that the data is now available
SetEvent(hEvent);
writer->Release();
}
void CefBrowserImpl::UIT_GetDocumentTextNotify(TargetFrame targetFrame,
CefStreamWriter* writer,
HANDLE hEvent)
{
REQUIRE_UIT();
WebFrame* frame;
if(targetFrame == TF_FOCUSED)
frame = UIT_GetWebView()->GetFocusedFrame();
else
frame = UIT_GetWebView()->GetMainFrame();
// Retrieve the document string
std::wstring str = webkit_glue::DumpDocumentText(frame);
std::string cstr = WideToUTF8(str);
// Write the document string to the stream
writer->Write(cstr.c_str(), cstr.size(), 1);
// Notify the calling thread that the data is now available
SetEvent(hEvent);
writer->Release();
}
void CefBrowserImpl::UIT_CanGoBackNotify(bool *retVal, HANDLE hEvent)
{
REQUIRE_UIT();
*retVal = UIT_CanGoBack();
// Notify the calling thread that the data is now available
SetEvent(hEvent);
}
void CefBrowserImpl::UIT_CanGoForwardNotify(bool *retVal, HANDLE hEvent)
{
REQUIRE_UIT();
*retVal = UIT_CanGoForward();
// Notify the calling thread that the data is now available
SetEvent(hEvent);
}
int CefBrowserImpl::UIT_SwitchFrameToPrintMediaType(WebFrame* frame) {
REQUIRE_UIT();
printing::PrintParams params;
print_context_.settings().RenderParams(&params);
float ratio = static_cast<float>(params.desired_dpi / params.dpi);
float paper_width = params.printable_size.width() * ratio;
float paper_height = params.printable_size.height() * ratio;
float minLayoutWidth = static_cast<float>(paper_width * params.min_shrink);
float maxLayoutWidth = static_cast<float>(paper_width * params.max_shrink);
// Safari uses: 765 & 1224. Margins aren't exactly the same either.
// Scale = 2.222 for MDI printer.
int pages;
int width;
if (!frame->SetPrintingMode(true,
minLayoutWidth,
maxLayoutWidth,
&width)) {
NOTREACHED();
pages = 0;
} else {
// Force to recalculate the height, otherwise it reuse the current window
// height as the default.
float effective_shrink = static_cast<float>(width) / paper_width;
gfx::Size page_size(width,
static_cast<int>(paper_height * effective_shrink) - 1);
WebView* view = frame->GetView();
if (view) {
// Hack around an issue where if the current view height is higher than
// the page height, empty pages will be printed even if the bottom of the
// web page is empty.
printing_view_size_ = view->GetSize();
view->Resize(page_size);
view->Layout();
}
pages = frame->ComputePageRects(params.printable_size);
DCHECK(pages);
}
return pages;
}
void CefBrowserImpl::UIT_SwitchFrameToDisplayMediaType(WebFrame* frame) {
REQUIRE_UIT();
// TODO(cef): Figure out how to make the frame redraw properly after printing
// to PDF file (currently leaves a white rectangle behind the save as dialog).
// Set the layout back to "normal" document; i.e. CSS media type = "screen".
frame->SetPrintingMode(false, 0, 0, NULL);
WebView* view = frame->GetView();
if (view) {
// Restore from the hack described at SwitchFrameToPrintMediaType().
view->Resize(printing_view_size_);
view->Layout();
printing_view_size_.SetSize(0, 0);
}
}
void CefBrowserImpl::UIT_PrintPage(int page_number, WebFrame* frame,
int total_pages) {
REQUIRE_UIT();
if (printing_view_size_.width() < 0) {
NOTREACHED();
return;
}
printing::PrintParams params;
const printing::PrintSettings &settings = print_context_.settings();
settings.RenderParams(&params);
gfx::Size src_size = frame->GetView()->GetSize();
double src_size_x = src_size.width();
double src_size_y = src_size.height();
double src_margin = .1 * src_size_x;
double dest_size_x = settings.page_setup_pixels().physical_size().width();
double dest_size_y = settings.page_setup_pixels().physical_size().height();
double dest_margin = .1 * dest_size_x;
print_context_.NewPage();
HDC hDC = print_context_.context();
BOOL res;
// Save the state to make sure the context this function call does not modify
// the device context.
int saved_state = SaveDC(hDC);
DCHECK_NE(saved_state, 0);
// 100% GDI based.
gfx::VectorCanvas canvas(hDC, (int)ceil(dest_size_x), (int)ceil(dest_size_y));
canvas.translate(SkDoubleToScalar(dest_margin),
SkDoubleToScalar(dest_margin));
canvas.scale(SkDoubleToScalar((dest_size_x - dest_margin * 2) / src_size_x),
SkDoubleToScalar((dest_size_y - dest_margin * 2) / src_size_y));
// Set the clipping region to be sure to not overflow.
SkRect clip_rect;
clip_rect.set(0, 0, SkDoubleToScalar(src_size_x),
SkDoubleToScalar(src_size_y));
canvas.clipRect(clip_rect);
if (!frame->SpoolPage(page_number-1, &canvas)) {
NOTREACHED() << "Printing page " << page_number << " failed.";
return;
}
res = RestoreDC(hDC, saved_state);
DCHECK_NE(res, 0);
if(handler_.get()) {
saved_state = SaveDC(hDC);
DCHECK_NE(saved_state, 0);
// Gather print header state information
RECT rect;
rect.left = (int)floor(dest_margin / 2);
rect.top = rect.left;
rect.right = (int)ceil(dest_size_x - dest_margin / 2);
rect.bottom = (int)ceil(dest_size_y - dest_margin / 2);
double scale = (double)settings.dpi() / (double)settings.desired_dpi;
CefPrintInfo printInfo;
printInfo.m_hDC = hDC;
printInfo.m_Rect = rect;
printInfo.m_Scale = scale;
std::wstring url = UTF8ToWide(frame->GetURL().spec());
std::wstring title = title_;
std::wstring topLeft, topCenter, topRight;
std::wstring bottomLeft, bottomCenter, bottomRight;
// allow the handler to format print header and/or footer
CefHandler::RetVal rv = handler_->HandlePrintHeaderFooter(this, printInfo,
url, title, page_number, total_pages, topLeft, topCenter, topRight,
bottomLeft, bottomCenter, bottomRight);
if(rv != CefHandler::RV_HANDLED) {
// Draw handler-defined headers and/or footers.
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = (int)ceil(10. * scale);
lf.lfPitchAndFamily = FF_SWISS;
HFONT hFont = CreateFontIndirect(&lf);
HFONT hOldFont = (HFONT)SelectObject(hDC, hFont);
COLORREF hOldColor = SetTextColor(hDC, RGB(0,0,0));
int hOldBkMode = SetBkMode(hDC, TRANSPARENT);
// TODO(cef): Keep the header strings inside a reasonable bounding box
// so that they don't overlap each other.
if(topLeft.size() > 0) {
DrawText(hDC, topLeft.c_str(), topLeft.size(), &rect,
DT_LEFT | DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS
| DT_EXPANDTABS | DT_NOPREFIX);
}
if(topCenter.size() > 0) {
DrawText(hDC, topCenter.c_str(), topCenter.size(), &rect,
DT_CENTER | DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS
| DT_EXPANDTABS | DT_NOPREFIX);
}
if(topRight.size() > 0) {
DrawText(hDC, topRight.c_str(), topRight.size(), &rect,
DT_RIGHT | DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS
| DT_EXPANDTABS | DT_NOPREFIX);
}
if(bottomLeft.size() > 0) {
DrawText(hDC, bottomLeft.c_str(), bottomLeft.size(), &rect,
DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS
| DT_EXPANDTABS | DT_NOPREFIX);
}
if(bottomCenter.size() > 0) {
DrawText(hDC, bottomCenter.c_str(), bottomCenter.size(), &rect,
DT_CENTER | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS
| DT_EXPANDTABS | DT_NOPREFIX);
}
if(bottomRight.size() > 0) {
DrawText(hDC, bottomRight.c_str(), bottomRight.size(), &rect,
DT_RIGHT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS
| DT_EXPANDTABS | DT_NOPREFIX);
}
SetTextColor(hDC, hOldColor);
SelectObject(hDC, hOldFont);
DeleteObject(hFont);
SetBkMode(hDC, hOldBkMode);
}
res = RestoreDC(hDC, saved_state);
DCHECK_NE(res, 0);
}
print_context_.PageDone();
}
void CefBrowserImpl::UIT_PrintPages(WebFrame* frame) {
REQUIRE_UIT();
TCHAR printername[512];
DWORD size = sizeof(printername)-1;
if(GetDefaultPrinter(printername, &size)) {
printing::PrintSettings settings;
settings.set_device_name(printername);
// Initialize it.
print_context_.InitWithSettings(settings);
}
if(print_context_.AskUserForSettings(
UIT_GetMainWndHandle(), UIT_GetPagesCount(frame))
!= printing::PrintingContext::OK)
return;
printing::PrintParams params;
const printing::PrintSettings &settings = print_context_.settings();
settings.RenderParams(&params);
// disable the web view so we don't see printing related layout changes on
// the screen
UIT_DisableWebView(true);
int pages = UIT_SwitchFrameToPrintMediaType(frame);
if (pages) {
bool old_state = MessageLoop::current()->NestableTasksAllowed();
MessageLoop::current()->SetNestableTasksAllowed(false);
// TODO(cef): Use the page title as the document name
print_context_.NewDocument(L"New Document");
if(settings.ranges.size() > 0) {
for (unsigned i = 0; i < settings.ranges.size(); ++i) {
const printing::PageRange& range = settings.ranges[i];
for(int i = range.from; i <= range.to; ++i)
UIT_PrintPage(i, frame, pages);
}
} else {
for(int i = 1; i <= pages; ++i)
UIT_PrintPage(i, frame, pages);
}
print_context_.DocumentDone();
MessageLoop::current()->SetNestableTasksAllowed(old_state);
}
UIT_SwitchFrameToDisplayMediaType(frame);
// re-enable web view
UIT_DisableWebView(false);
}
int CefBrowserImpl::UIT_GetPagesCount(WebFrame* frame)
{
REQUIRE_UIT();
int pages = UIT_SwitchFrameToPrintMediaType(frame);
UIT_SwitchFrameToDisplayMediaType(frame);
return pages;
}
void CefBrowserImpl::UIT_CaptureWebViewBitmap(HBITMAP &bitmap, SIZE &size)
{
REQUIRE_UIT();
webkit_glue::CaptureWebViewBitmap(UIT_GetMainWndHandle(), UIT_GetWebView(),
bitmap, size);
}
void CefBrowserImpl::UIT_SetWebViewBitmap(HBITMAP bitmap, SIZE size)
{
REQUIRE_UIT();
if(webview_bitmap_)
DeleteObject(webview_bitmap_);
webview_bitmap_ = bitmap;
webview_bitmap_size_ = size;
}
void CefBrowserImpl::UIT_DisableWebView(bool val)
{
REQUIRE_UIT();
if(val) {
// disable the web view window
if(webview_bitmap_ != NULL)
return;
HBITMAP bitmap;
SIZE size;
UIT_CaptureWebViewBitmap(bitmap, size);
UIT_SetWebViewBitmap(bitmap, size);
DWORD dwStyle = GetWindowLong(UIT_GetWebViewWndHandle(), GWL_STYLE);
SetWindowLong(UIT_GetWebViewWndHandle(), GWL_STYLE, dwStyle & ~WS_VISIBLE);
RedrawWindow(UIT_GetMainWndHandle(), NULL, NULL, RDW_INVALIDATE);
} else if(webview_bitmap_) {
// enable the web view window
SIZE size = {0,0};
UIT_SetWebViewBitmap(NULL, size);
DWORD dwStyle = GetWindowLong(UIT_GetWebViewWndHandle(), GWL_STYLE);
SetWindowLong(UIT_GetWebViewWndHandle(), GWL_STYLE, dwStyle | WS_VISIBLE);
RedrawWindow(UIT_GetMainWndHandle(), NULL, NULL, RDW_INVALIDATE);
}
}

View File

@ -0,0 +1,258 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "browser_navigation_controller.h"
#include "browser_impl.h"
#include "base/logging.h"
#include "net/base/upload_data.h"
#include "webkit/glue/webhistoryitem.h"
// ----------------------------------------------------------------------------
// BrowserNavigationEntry
BrowserNavigationEntry::BrowserNavigationEntry()
: page_id_(-1) {
}
BrowserNavigationEntry::BrowserNavigationEntry(int page_id,
const GURL& url,
const std::wstring& title,
const std::wstring& target_frame,
const std::wstring& method,
net::UploadData *upload,
const WebRequest::HeaderMap& headers)
: page_id_(page_id),
url_(url),
title_(title),
target_frame_(target_frame),
method_(method),
upload_(upload),
headers_(headers) {
}
BrowserNavigationEntry::~BrowserNavigationEntry() {
}
void BrowserNavigationEntry::SetContentState(const std::string& state) {
cached_history_item_ = NULL; // invalidate our cached item
state_ = state;
}
WebHistoryItem* BrowserNavigationEntry::GetHistoryItem() const {
// TODO(port): temporary hack to get a basic test shell executable going.
#if !defined(OS_LINUX)
if (!cached_history_item_) {
BrowserExtraRequestData* extra_data =
new BrowserExtraRequestData(GetPageID());
cached_history_item_ =
WebHistoryItem::Create(GetURL(), GetTitle(), GetContentState(),
extra_data);
}
#endif
return cached_history_item_;
}
// ----------------------------------------------------------------------------
// BrowserNavigationController
BrowserNavigationController::BrowserNavigationController(CefBrowserImpl* shell)
: pending_entry_(NULL),
last_committed_entry_index_(-1),
pending_entry_index_(-1),
browser_(shell),
max_page_id_(-1) {
}
BrowserNavigationController::~BrowserNavigationController() {
DiscardPendingEntry();
}
void BrowserNavigationController::Reset() {
entries_.clear();
DiscardPendingEntry();
last_committed_entry_index_ = -1;
}
void BrowserNavigationController::Reload() {
// Base the navigation on where we are now...
int current_index = GetCurrentEntryIndex();
// If we are no where, then we can't reload. TODO(darin): We should add a
// CanReload method.
if (current_index == -1)
return;
DiscardPendingEntry();
pending_entry_index_ = current_index;
NavigateToPendingEntry(true);
}
void BrowserNavigationController::GoToOffset(int offset) {
int index = last_committed_entry_index_ + offset;
if (index < 0 || index >= GetEntryCount())
return;
GoToIndex(index);
}
void BrowserNavigationController::GoToIndex(int index) {
DCHECK(index >= 0);
DCHECK(index < static_cast<int>(entries_.size()));
DiscardPendingEntry();
pending_entry_index_ = index;
NavigateToPendingEntry(false);
}
void BrowserNavigationController::LoadEntry(BrowserNavigationEntry* entry) {
// When navigating to a new page, we don't know for sure if we will actually
// end up leaving the current page. The new page load could for example
// result in a download or a 'no content' response (e.g., a mailto: URL).
DiscardPendingEntry();
pending_entry_ = entry;
NavigateToPendingEntry(false);
}
BrowserNavigationEntry* BrowserNavigationController::GetLastCommittedEntry() const {
if (last_committed_entry_index_ == -1)
return NULL;
return entries_[last_committed_entry_index_].get();
}
BrowserNavigationEntry* BrowserNavigationController::GetActiveEntry() const {
BrowserNavigationEntry* entry = pending_entry_;
if (!entry)
entry = GetLastCommittedEntry();
return entry;
}
int BrowserNavigationController::GetCurrentEntryIndex() const {
if (pending_entry_index_ != -1)
return pending_entry_index_;
return last_committed_entry_index_;
}
BrowserNavigationEntry* BrowserNavigationController::GetEntryAtOffset(
int offset) const {
int index = last_committed_entry_index_ + offset;
if (index < 0 || index >= GetEntryCount())
return NULL;
return entries_[index].get();
}
BrowserNavigationEntry* BrowserNavigationController::GetEntryWithPageID(
int32 page_id) const {
int index = GetEntryIndexWithPageID(page_id);
return (index != -1) ? entries_[index].get() : NULL;
}
void BrowserNavigationController::DidNavigateToEntry(BrowserNavigationEntry* entry) {
// If the entry is that of a page with PageID larger than any this Tab has
// seen before, then consider it a new navigation.
if (entry->GetPageID() > GetMaxPageID()) {
InsertEntry(entry);
return;
}
// Otherwise, we just need to update an existing entry with matching PageID.
// If the existing entry corresponds to the entry which is pending, then we
// must update the current entry index accordingly. When navigating to the
// same URL, a new PageID is not created.
int existing_entry_index = GetEntryIndexWithPageID(entry->GetPageID());
BrowserNavigationEntry* existing_entry = (existing_entry_index != -1) ?
entries_[existing_entry_index].get() : NULL;
if (!existing_entry) {
// No existing entry, then simply ignore this navigation!
DLOG(WARNING) << "ignoring navigation for page: " << entry->GetPageID();
} else if (existing_entry == pending_entry_) {
// The given entry might provide a new URL... e.g., navigating back to a
// page in session history could have resulted in a new client redirect.
existing_entry->SetURL(entry->GetURL());
existing_entry->SetContentState(entry->GetContentState());
last_committed_entry_index_ = pending_entry_index_;
pending_entry_index_ = -1;
pending_entry_ = NULL;
} else if (pending_entry_ && pending_entry_->GetPageID() == -1 &&
pending_entry_->GetURL() == existing_entry->GetURL()) {
// Not a new navigation
DiscardPendingEntry();
} else {
// The given entry might provide a new URL... e.g., navigating to a page
// might result in a client redirect, which should override the URL of the
// existing entry.
existing_entry->SetURL(entry->GetURL());
existing_entry->SetContentState(entry->GetContentState());
// The navigation could have been issued by the renderer, so be sure that
// we update our current index.
last_committed_entry_index_ = existing_entry_index;
}
delete entry;
UpdateMaxPageID();
}
void BrowserNavigationController::DiscardPendingEntry() {
if (pending_entry_index_ == -1)
delete pending_entry_;
pending_entry_ = NULL;
pending_entry_index_ = -1;
}
void BrowserNavigationController::InsertEntry(BrowserNavigationEntry* entry) {
DiscardPendingEntry();
// Prune any entry which are in front of the current entry
int current_size = static_cast<int>(entries_.size());
if (current_size > 0) {
while (last_committed_entry_index_ < (current_size - 1)) {
entries_.pop_back();
current_size--;
}
}
entries_.push_back(linked_ptr<BrowserNavigationEntry>(entry));
last_committed_entry_index_ = static_cast<int>(entries_.size()) - 1;
UpdateMaxPageID();
}
int BrowserNavigationController::GetEntryIndexWithPageID(int32 page_id) const {
for (int i = static_cast<int>(entries_.size())-1; i >= 0; --i) {
if (entries_[i]->GetPageID() == page_id)
return i;
}
return -1;
}
void BrowserNavigationController::NavigateToPendingEntry(bool reload) {
// For session history navigations only the pending_entry_index_ is set.
if (!pending_entry_) {
DCHECK(pending_entry_index_ != -1);
pending_entry_ = entries_[pending_entry_index_].get();
}
if (browser_->UIT_Navigate(*pending_entry_, reload)) {
// Note: this is redundant if navigation completed synchronously because
// DidNavigateToEntry call this as well.
UpdateMaxPageID();
} else {
DiscardPendingEntry();
}
}
void BrowserNavigationController::UpdateMaxPageID() {
BrowserNavigationEntry* entry = GetActiveEntry();
if (entry)
max_page_id_ = std::max(max_page_id_, entry->GetPageID());
}

View File

@ -0,0 +1,220 @@
// Copyright (c) 2008 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.
#ifndef _BROWSER_NAVIGATION_CONTROLLER_H
#define _BROWSER_NAVIGATION_CONTROLLER_H
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/linked_ptr.h"
#include "base/ref_counted.h"
#include "googleurl/src/gurl.h"
#include "webkit/glue/weburlrequest.h"
namespace net {
class UploadData;
}
class GURL;
class CefBrowserImpl;
class WebHistoryItem;
// Associated with browser-initated navigations to hold tracking data.
class BrowserExtraRequestData : public WebRequest::ExtraData {
public:
BrowserExtraRequestData(int32 pending_page_id)
: WebRequest::ExtraData(),
pending_page_id(pending_page_id),
request_committed(false) {
}
// Contains the page_id for this navigation or -1 if there is none yet.
int32 pending_page_id;
// True if we have already processed the "DidCommitLoad" event for this
// request. Used by session history.
bool request_committed;
};
// Stores one back/forward navigation state for the test shell.
class BrowserNavigationEntry {
public:
BrowserNavigationEntry();
BrowserNavigationEntry(int page_id,
const GURL& url,
const std::wstring& title,
const std::wstring& target_frame,
const std::wstring& method,
net::UploadData *upload,
const WebRequest::HeaderMap& headers);
// Virtual to allow test_shell to extend the class.
~BrowserNavigationEntry();
// Set / Get the URI
void SetURL(const GURL& url) { url_ = url; }
const GURL& GetURL() const { return url_; }
// Set / Get the title
void SetTitle(const std::wstring& a_title) { title_ = a_title; }
const std::wstring& GetTitle() const { return title_; }
// Set / Get opaque state.
// WARNING: This state is saved to the database and used to restore previous
// states. If you use write a custom TabContents and provide your own
// state make sure you have the ability to modify the format in the future
// while being able to deal with older versions.
void SetContentState(const std::string& state);
const std::string& GetContentState() const { return state_; }
// Get the page id corresponding to the tab's state.
void SetPageID(int page_id) { page_id_ = page_id; }
int32 GetPageID() const { return page_id_; }
WebHistoryItem* GetHistoryItem() const;
const std::wstring& GetTargetFrame() const { return target_frame_; }
const std::wstring& GetMethod() const { return method_; }
net::UploadData* GetUploadData() const { return upload_.get(); }
const WebRequest::HeaderMap& GetHeaders() const { return headers_; }
private:
// Describes the current page that the tab represents. This is not relevant
// for all tab contents types.
int32 page_id_;
GURL url_;
std::wstring title_;
std::string state_;
std::wstring method_;
scoped_refptr<net::UploadData> upload_;
WebRequest::HeaderMap headers_;
mutable scoped_refptr<WebHistoryItem> cached_history_item_;
std::wstring target_frame_;
DISALLOW_COPY_AND_ASSIGN(BrowserNavigationEntry);
};
// Browser's NavigationController. The goal is to be as close to the Chrome
// version as possible.
class BrowserNavigationController {
public:
BrowserNavigationController(CefBrowserImpl* shell);
~BrowserNavigationController();
void Reset();
// Causes the controller to reload the current (or pending) entry.
void Reload();
// Causes the controller to go to the specified offset from current. Does
// nothing if out of bounds.
void GoToOffset(int offset);
// Causes the controller to go to the specified index.
void GoToIndex(int index);
// Causes the controller to load the specified entry. The controller
// assumes ownership of the entry.
// NOTE: Do not pass an entry that the controller already owns!
void LoadEntry(BrowserNavigationEntry* entry);
// Returns the last committed entry, which may be null if there are no
// committed entries.
BrowserNavigationEntry* GetLastCommittedEntry() const;
// Returns the number of entries in the NavigationControllerBase, excluding
// the pending entry if there is one.
int GetEntryCount() const {
return static_cast<int>(entries_.size());
}
// Returns the active entry, which is the pending entry if a navigation is in
// progress or the last committed entry otherwise. NOTE: This can be NULL!!
//
// If you are trying to get the current state of the NavigationControllerBase,
// this is the method you will typically want to call.
BrowserNavigationEntry* GetActiveEntry() const;
// Returns the index from which we would go back/forward or reload. This is
// the last_committed_entry_index_ if pending_entry_index_ is -1. Otherwise,
// it is the pending_entry_index_.
int GetCurrentEntryIndex() const;
// Returns the entry at the specified offset from current. Returns NULL
// if out of bounds.
BrowserNavigationEntry* GetEntryAtOffset(int offset) const;
// Return the entry with the corresponding type and page_id, or NULL if
// not found.
BrowserNavigationEntry* GetEntryWithPageID(int32 page_id) const;
// Returns the index of the last committed entry.
int GetLastCommittedEntryIndex() const {
return last_committed_entry_index_;
}
// Returns true if there are no entries before the last committed entry.
bool IsAtStart() const {
return (GetLastCommittedEntryIndex() == 0);
}
// Returns true if there are no entries after the last committed entry.
bool IsAtEnd() const {
return (GetLastCommittedEntryIndex() == GetEntryCount()-1);
}
// Used to inform us of a navigation being committed for a tab. We will take
// ownership of the entry. Any entry located forward to the current entry will
// be deleted. The new entry becomes the current entry.
void DidNavigateToEntry(BrowserNavigationEntry* entry);
// Used to inform us to discard its pending entry.
void DiscardPendingEntry();
private:
// Inserts an entry after the current position, removing all entries after it.
// The new entry will become the active one.
void InsertEntry(BrowserNavigationEntry* entry);
int GetMaxPageID() const { return max_page_id_; }
void NavigateToPendingEntry(bool reload);
// Return the index of the entry with the corresponding type and page_id,
// or -1 if not found.
int GetEntryIndexWithPageID(int32 page_id) const;
// Updates the max page ID with that of the given entry, if is larger.
void UpdateMaxPageID();
// List of NavigationEntry for this tab
typedef std::vector< linked_ptr<BrowserNavigationEntry> > NavigationEntryList;
typedef NavigationEntryList::iterator NavigationEntryListIterator;
NavigationEntryList entries_;
// An entry we haven't gotten a response for yet. This will be discarded
// when we navigate again. It's used only so we know what the currently
// displayed tab is.
BrowserNavigationEntry* pending_entry_;
// currently visible entry
int last_committed_entry_index_;
// index of pending entry if it is in entries_, or -1 if pending_entry_ is a
// new entry (created by LoadURL).
int pending_entry_index_;
CefBrowserImpl* browser_;
int max_page_id_;
DISALLOW_EVIL_CONSTRUCTORS(BrowserNavigationController);
};
#endif // _BROWSER_NAVIGATION_CONTROLLER_H

View File

@ -0,0 +1,47 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "browser_request_context.h"
#include "net/base/cookie_monster.h"
#include "webkit/glue/webkit_glue.h"
BrowserRequestContext::BrowserRequestContext() {
Init(std::wstring(), net::HttpCache::NORMAL);
}
BrowserRequestContext::BrowserRequestContext(
const std::wstring& cache_path,
net::HttpCache::Mode cache_mode) {
Init(cache_path, cache_mode);
}
void BrowserRequestContext::Init(
const std::wstring& cache_path,
net::HttpCache::Mode cache_mode) {
cookie_store_ = new net::CookieMonster();
user_agent_ = webkit_glue::GetUserAgent();
// hard-code A-L and A-C for test shells
accept_language_ = "en-us,en";
accept_charset_ = "iso-8859-1,*,utf-8";
net::HttpCache *cache;
if (cache_path.empty()) {
cache = new net::HttpCache(NULL, 0);
} else {
cache = new net::HttpCache(NULL, cache_path, 0);
}
cache->set_mode(cache_mode);
http_transaction_factory_ = cache;
}
BrowserRequestContext::~BrowserRequestContext() {
delete cookie_store_;
delete http_transaction_factory_;
}

View File

@ -0,0 +1,30 @@
// Copyright (c) 2008 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.
#ifndef _BROWSER_REQUEST_CONTEXT_H
#define _BROWSER_REQUEST_CONTEXT_H
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
// A basic URLRequestContext that only provides an in-memory cookie store.
class BrowserRequestContext : public URLRequestContext {
public:
// Use an in-memory cache
BrowserRequestContext();
// Use an on-disk cache at the specified location. Optionally, use the cache
// in playback or record mode.
BrowserRequestContext(const std::wstring& cache_path,
net::HttpCache::Mode cache_mode);
~BrowserRequestContext();
private:
void Init(const std::wstring& cache_path, net::HttpCache::Mode cache_mode);
};
#endif // _BROWSER_REQUEST_CONTEXT_H

View File

@ -0,0 +1,656 @@
// Copyright (c) 2008 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.
//
// This file contains an implementation of the ResourceLoaderBridge class.
// The class is implemented using URLRequest, meaning it is a "simple" version
// that directly issues requests. The more complicated one used in the
// browser uses IPC.
//
// Because URLRequest only provides an asynchronous resource loading API, this
// file makes use of URLRequest from a background IO thread. Requests for
// cookies and synchronously loaded resources result in the main thread of the
// application blocking until the IO thread completes the operation. (See
// GetCookies and SyncLoad)
//
// Main thread IO thread
// ----------- ---------
// ResourceLoaderBridge <---o---------> RequestProxy (normal case)
// \ -> URLRequest
// o-------> SyncRequestProxy (synchronous case)
// -> URLRequest
// SetCookie <------------------------> CookieSetter
// -> net_util::SetCookie
// GetCookies <-----------------------> CookieGetter
// -> net_util::GetCookies
//
// NOTE: The implementation in this file may be used to have WebKit fetch
// resources in-process. For example, it is handy for building a single-
// process WebKit embedding (e.g., test_shell) that can use URLRequest to
// perform URL loads. See renderer/resource_dispatcher.h for details on an
// alternate implementation that defers fetching to another process.
#include "precompiled_libcef.h"
#include "browser_resource_loader_bridge.h"
#include "browser_request_context.h"
#include "browser_impl.h"
#include "request_impl.h"
#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "base/string_util.h"
#include "base/thread.h"
#include "base/waitable_event.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_util.h"
#include "net/base/upload_data.h"
#include "net/url_request/url_request.h"
#include "webkit/glue/resource_loader_bridge.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webview.h"
using webkit_glue::ResourceLoaderBridge;
using net::HttpResponseHeaders;
namespace {
//-----------------------------------------------------------------------------
URLRequestContext* request_context = NULL;
base::Thread* io_thread = NULL;
class IOThread : public base::Thread {
public:
IOThread() : base::Thread("IOThread") {
}
~IOThread() {
// We cannot rely on our base class to stop the thread since we want our
// CleanUp function to run.
Stop();
}
virtual void CleanUp() {
if (request_context) {
request_context->Release();
request_context = NULL;
}
}
};
bool EnsureIOThread() {
if (io_thread)
return true;
if (!request_context)
BrowserResourceLoaderBridge::Init(NULL);
io_thread = new IOThread();
base::Thread::Options options;
options.message_loop_type = MessageLoop::TYPE_IO;
return io_thread->StartWithOptions(options);
}
//-----------------------------------------------------------------------------
struct RequestParams {
std::string method;
GURL url;
GURL policy_url;
GURL referrer;
std::string headers;
int load_flags;
scoped_refptr<net::UploadData> upload;
};
// The RequestProxy does most of its work on the IO thread. The Start and
// Cancel methods are proxied over to the IO thread, where an URLRequest object
// is instantiated.
class RequestProxy : public URLRequest::Delegate,
public base::RefCountedThreadSafe<RequestProxy> {
public:
// Takes ownership of the params.
RequestProxy(CefRefPtr<CefBrowser> browser)
: browser_(browser)
{
}
virtual ~RequestProxy() {
// If we have a request, then we'd better be on the io thread!
DCHECK(!request_.get() ||
MessageLoop::current() == io_thread->message_loop());
}
void DropPeer() {
peer_ = NULL;
}
void Start(ResourceLoaderBridge::Peer* peer, RequestParams* params) {
peer_ = peer;
owner_loop_ = MessageLoop::current();
// proxy over to the io thread
io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
this, &RequestProxy::AsyncStart, params));
}
void Cancel() {
// proxy over to the io thread
io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
this, &RequestProxy::AsyncCancel));
}
protected:
// --------------------------------------------------------------------------
// The following methods are called on the owner's thread in response to
// various URLRequest callbacks. The event hooks, defined below, trigger
// these methods asynchronously.
void NotifyReceivedRedirect(const GURL& new_url) {
if (peer_)
peer_->OnReceivedRedirect(new_url);
}
void NotifyReceivedResponse(const ResourceLoaderBridge::ResponseInfo& info,
bool content_filtered) {
if (peer_)
peer_->OnReceivedResponse(info, content_filtered);
}
void NotifyReceivedData(int bytes_read) {
if (!peer_)
return;
// Make a local copy of buf_, since AsyncReadData reuses it.
scoped_array<char> buf_copy(new char[bytes_read]);
memcpy(buf_copy.get(), buf_, bytes_read);
// Continue reading more data into buf_
// Note: Doing this before notifying our peer ensures our load events get
// dispatched in a manner consistent with DumpRenderTree (and also avoids a
// race condition). If the order of the next 2 functions were reversed, the
// peer could generate new requests in reponse to the received data, which
// when run on the io thread, could race against this function in doing
// another InvokeLater. See bug 769249.
io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
this, &RequestProxy::AsyncReadData));
peer_->OnReceivedData(buf_copy.get(), bytes_read);
}
void NotifyCompletedRequest(const URLRequestStatus& status) {
if (peer_) {
peer_->OnCompletedRequest(status);
DropPeer(); // ensure no further notifications
}
}
// --------------------------------------------------------------------------
// The following methods are called on the io thread. They correspond to
// actions performed on the owner's thread.
void AsyncStart(RequestParams* params) {
bool handled = false;
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get())
{
// Build the request object for passing to the handler
CefRefPtr<CefRequest> request(new CefRequestImpl());
CefRequestImpl* requestimpl = static_cast<CefRequestImpl*>(request.get());
requestimpl->SetURL(UTF8ToWide(params->url.spec()));
requestimpl->SetMethod(UTF8ToWide(params->method));
// TODO(cef): Parse the extra header values from params->headers and
// add to the header map.
CefRequest::HeaderMap headerMap;
headerMap.insert(
std::make_pair(L"Referrer", UTF8ToWide(params->referrer.spec())));
requestimpl->SetHeaderMap(headerMap);
scoped_refptr<net::UploadData> upload = params->upload;
CefRefPtr<CefPostData> postdata;
if(upload.get()) {
postdata = new CefPostDataImpl();
static_cast<CefPostDataImpl*>(postdata.get())->Set(*upload.get());
requestimpl->SetPostData(postdata);
}
int loadFlags = params->load_flags;
// Handler output will be returned in these variables
std::wstring redirectUrl;
CefRefPtr<CefStreamReader> resourceStream;
std::wstring mimeType;
CefHandler::RetVal rv = handler->HandleBeforeResourceLoad(
browser_, request, redirectUrl, resourceStream, mimeType, loadFlags);
if(rv == CefHandler::RV_HANDLED) {
// cancel the resource load
handled = true;
OnCompletedRequest(URLRequestStatus(URLRequestStatus::CANCELED, 0));
} else if(!redirectUrl.empty()) {
// redirect to the specified URL
params->url = GURL(WideToUTF8(redirectUrl));
OnReceivedRedirect(params->url);
} else if(resourceStream.get()) {
// load from the provided resource stream
handled = true;
long offset = resourceStream->Seek(0, SEEK_END);
resourceStream->Seek(0, SEEK_SET);
resource_stream_ = resourceStream;
ResourceLoaderBridge::ResponseInfo info;
info.content_length = static_cast<int64>(offset);
if(!mimeType.empty())
info.mime_type = WideToUTF8(mimeType);
OnReceivedResponse(info, false);
AsyncReadData();
}
}
if(!handled)
{
request_.reset(new URLRequest(params->url, this));
request_->set_method(params->method);
request_->set_policy_url(params->policy_url);
request_->set_referrer(params->referrer.spec());
request_->SetExtraRequestHeaders(params->headers);
request_->set_load_flags(params->load_flags);
request_->set_upload(params->upload.get());
request_->set_context(request_context);
request_->Start();
}
delete params;
}
void AsyncCancel() {
// This can be null in cases where the request is already done.
if (!resource_stream_.get() && !request_.get())
return;
request_->Cancel();
Done();
}
void AsyncReadData() {
if(resource_stream_.get()) {
// Read from the handler-provided resource stream
int bytes_read = resource_stream_->Read(buf_, 1, sizeof(buf_));
if(bytes_read > 0) {
OnReceivedData(bytes_read);
} else {
Done();
}
return;
}
// This can be null in cases where the request is already done.
if (!request_.get())
return;
if (request_->status().is_success()) {
int bytes_read;
if (request_->Read(buf_, sizeof(buf_), &bytes_read) && bytes_read) {
OnReceivedData(bytes_read);
} else if (!request_->status().is_io_pending()) {
Done();
} // else wait for OnReadCompleted
} else {
Done();
}
}
// --------------------------------------------------------------------------
// The following methods are event hooks (corresponding to URLRequest
// callbacks) that run on the IO thread. They are designed to be overridden
// by the SyncRequestProxy subclass.
virtual void OnReceivedRedirect(const GURL& new_url) {
owner_loop_->PostTask(FROM_HERE, NewRunnableMethod(
this, &RequestProxy::NotifyReceivedRedirect, new_url));
}
virtual void OnReceivedResponse(
const ResourceLoaderBridge::ResponseInfo& info,
bool content_filtered) {
owner_loop_->PostTask(FROM_HERE, NewRunnableMethod(
this, &RequestProxy::NotifyReceivedResponse, info, content_filtered));
}
virtual void OnReceivedData(int bytes_read) {
owner_loop_->PostTask(FROM_HERE, NewRunnableMethod(
this, &RequestProxy::NotifyReceivedData, bytes_read));
}
virtual void OnCompletedRequest(const URLRequestStatus& status) {
owner_loop_->PostTask(FROM_HERE, NewRunnableMethod(
this, &RequestProxy::NotifyCompletedRequest, status));
}
// --------------------------------------------------------------------------
// URLRequest::Delegate implementation:
virtual void OnReceivedRedirect(URLRequest* request,
const GURL& new_url) {
DCHECK(request->status().is_success());
OnReceivedRedirect(new_url);
}
virtual void OnResponseStarted(URLRequest* request) {
if (request->status().is_success()) {
ResourceLoaderBridge::ResponseInfo info;
info.request_time = request->request_time();
info.response_time = request->response_time();
info.headers = request->response_headers();
request->GetMimeType(&info.mime_type);
request->GetCharset(&info.charset);
OnReceivedResponse(info, false);
AsyncReadData(); // start reading
} else {
Done();
}
}
virtual void OnReadCompleted(URLRequest* request, int bytes_read) {
if (request->status().is_success() && bytes_read > 0) {
OnReceivedData(bytes_read);
} else {
Done();
}
}
// --------------------------------------------------------------------------
// Helpers and data:
void Done() {
if(resource_stream_.get()) {
// Resource stream reads always complete successfully
OnCompletedRequest(URLRequestStatus(URLRequestStatus::SUCCESS, 0));
resource_stream_ = NULL;
} else {
DCHECK(request_.get());
OnCompletedRequest(request_->status());
request_.reset(); // destroy on the io thread
}
}
scoped_ptr<URLRequest> request_;
CefRefPtr<CefStreamReader> resource_stream_;
// Size of our async IO data buffers
static const int kDataSize = 16*1024;
// read buffer for async IO
char buf_[kDataSize];
CefRefPtr<CefBrowser> browser_;
MessageLoop* owner_loop_;
// This is our peer in WebKit (implemented as ResourceHandleInternal). We do
// not manage its lifetime, and we may only access it from the owner's
// message loop (owner_loop_).
ResourceLoaderBridge::Peer* peer_;
};
//-----------------------------------------------------------------------------
class SyncRequestProxy : public RequestProxy {
public:
explicit SyncRequestProxy(CefRefPtr<CefBrowser> browser,
ResourceLoaderBridge::SyncLoadResponse* result)
: RequestProxy(browser), result_(result), event_(true, false) {
}
void WaitForCompletion() {
if (!event_.Wait())
NOTREACHED();
}
// --------------------------------------------------------------------------
// Event hooks that run on the IO thread:
virtual void OnReceivedRedirect(const GURL& new_url) {
result_->url = new_url;
}
virtual void OnReceivedResponse(
const ResourceLoaderBridge::ResponseInfo& info,
bool content_filtered) {
*static_cast<ResourceLoaderBridge::ResponseInfo*>(result_) = info;
}
virtual void OnReceivedData(int bytes_read) {
result_->data.append(buf_, bytes_read);
AsyncReadData(); // read more (may recurse)
}
virtual void OnCompletedRequest(const URLRequestStatus& status) {
result_->status = status;
event_.Signal();
}
private:
ResourceLoaderBridge::SyncLoadResponse* result_;
base::WaitableEvent event_;
};
//-----------------------------------------------------------------------------
class ResourceLoaderBridgeImpl : public ResourceLoaderBridge {
public:
ResourceLoaderBridgeImpl(CefRefPtr<CefBrowser> browser,
const std::string& method,
const GURL& url,
const GURL& policy_url,
const GURL& referrer,
const std::string& headers,
int load_flags)
: browser_(browser),
params_(new RequestParams),
proxy_(NULL) {
params_->method = method;
params_->url = url;
params_->policy_url = policy_url;
params_->referrer = referrer;
params_->headers = headers;
params_->load_flags = load_flags;
}
virtual ~ResourceLoaderBridgeImpl() {
if (proxy_) {
proxy_->DropPeer();
// Let the proxy die on the IO thread
io_thread->message_loop()->ReleaseSoon(FROM_HERE, proxy_);
}
}
// --------------------------------------------------------------------------
// ResourceLoaderBridge implementation:
virtual void AppendDataToUpload(const char* data, int data_len) {
DCHECK(params_.get());
if (!params_->upload)
params_->upload = new net::UploadData();
params_->upload->AppendBytes(data, data_len);
}
virtual void AppendFileRangeToUpload(const std::wstring& file_path,
uint64 offset, uint64 length) {
DCHECK(params_.get());
if (!params_->upload)
params_->upload = new net::UploadData();
params_->upload->AppendFileRange(file_path, offset, length);
}
virtual bool Start(Peer* peer) {
DCHECK(!proxy_);
if (!EnsureIOThread())
return false;
proxy_ = new RequestProxy(browser_);
proxy_->AddRef();
proxy_->Start(peer, params_.release());
return true; // Any errors will be reported asynchronously.
}
virtual void Cancel() {
DCHECK(proxy_);
proxy_->Cancel();
}
virtual void SetDefersLoading(bool value) {
// TODO(darin): implement me
}
virtual void SyncLoad(SyncLoadResponse* response) {
DCHECK(!proxy_);
if (!EnsureIOThread())
return;
// this may change as the result of a redirect
response->url = params_->url;
proxy_ = new SyncRequestProxy(browser_, response);
proxy_->AddRef();
proxy_->Start(NULL, params_.release());
static_cast<SyncRequestProxy*>(proxy_)->WaitForCompletion();
}
private:
CefRefPtr<CefBrowser> browser_;
// Ownership of params_ is transfered to the proxy when the proxy is created.
scoped_ptr<RequestParams> params_;
// The request proxy is allocated when we start the request, and then it
// sticks around until this ResourceLoaderBridge is destroyed.
RequestProxy* proxy_;
};
//-----------------------------------------------------------------------------
class CookieSetter : public base::RefCountedThreadSafe<CookieSetter> {
public:
void Set(const GURL& url, const std::string& cookie) {
DCHECK(MessageLoop::current() == io_thread->message_loop());
request_context->cookie_store()->SetCookie(url, cookie);
}
};
class CookieGetter : public base::RefCountedThreadSafe<CookieGetter> {
public:
CookieGetter() : event_(false, false) {
}
void Get(const GURL& url) {
result_ = request_context->cookie_store()->GetCookies(url);
event_.Signal();
}
std::string GetResult() {
if (!event_.Wait())
NOTREACHED();
return result_;
}
private:
base::WaitableEvent event_;
std::string result_;
};
} // anonymous namespace
//-----------------------------------------------------------------------------
namespace webkit_glue {
// factory function
ResourceLoaderBridge* ResourceLoaderBridge::Create(
WebFrame* webframe,
const std::string& method,
const GURL& url,
const GURL& policy_url,
const GURL& referrer,
const std::string& headers,
int load_flags,
int origin_pid,
ResourceType::Type request_type,
bool mixed_contents) {
return new ResourceLoaderBridgeImpl(
(webframe->GetView()->GetDelegate() ?
static_cast<BrowserWebViewDelegate*>(
webframe->GetView()->GetDelegate())->GetBrowser() : NULL),
method, url, policy_url, referrer, headers, load_flags);
}
void SetCookie(const GURL& url, const GURL& policy_url,
const std::string& cookie) {
// Proxy to IO thread to synchronize w/ network loading.
if (!EnsureIOThread()) {
NOTREACHED();
return;
}
scoped_refptr<CookieSetter> cookie_setter = new CookieSetter();
io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
cookie_setter.get(), &CookieSetter::Set, url, cookie));
}
std::string GetCookies(const GURL& url, const GURL& policy_url) {
// Proxy to IO thread to synchronize w/ network loading
if (!EnsureIOThread()) {
NOTREACHED();
return std::string();
}
scoped_refptr<CookieGetter> getter = new CookieGetter();
io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
getter.get(), &CookieGetter::Get, url));
return getter->GetResult();
}
} // namespace webkit_glue
//-----------------------------------------------------------------------------
// static
void BrowserResourceLoaderBridge::Init(URLRequestContext* context) {
// Make sure to stop any existing IO thread since it may be using the
// current request context.
Shutdown();
if (context) {
request_context = context;
} else {
request_context = new BrowserRequestContext();
}
request_context->AddRef();
}
// static
void BrowserResourceLoaderBridge::Shutdown() {
if (io_thread) {
delete io_thread;
io_thread = NULL;
DCHECK(!request_context) << "should have been nulled by thread dtor";
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) 2008 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.
#ifndef _BROWSER_RESOURCE_LOADER_BRIDGE_H
#define _BROWSER_RESOURCE_LOADER_BRIDGE_H
#include "base/ref_counted.h"
class URLRequestContext;
class BrowserResourceLoaderBridge {
public:
// Call this function to initialize the simple resource loader bridge. If
// the given context is null, then a default BrowserRequestContext will be
// instantiated. Otherwise, a reference is taken to the given request
// context, which will be released when Shutdown is called. The caller
// should not hold another reference to the request context! It is safe to
// call this function multiple times.
//
// NOTE: If this function is not called, then a default request context will
// be initialized lazily.
//
static void Init(URLRequestContext* context);
// Call this function to shutdown the simple resource loader bridge.
static void Shutdown();
};
#endif // _BROWSER_RESOURCE_LOADER_BRIDGE_H

View File

@ -0,0 +1,153 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "browser_webkit_glue.h"
#include "base/compiler_specific.h"
#include "config.h"
#include "webkit_version.h"
MSVC_PUSH_WARNING_LEVEL(0);
#include "Markup.h"
#include "webkit/glue/webframe_impl.h"
MSVC_POP_WARNING();
#undef LOG
#include "base/path_service.h"
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "base/win_util.h"
#include "net/base/mime_util.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webkit_resources.h"
namespace webkit_glue {
void PrefetchDns(const std::string& hostname) {}
void PrecacheUrl(const char16* url, int url_length) {}
void AppendToLog(const char* file, int line, const char* msg) {
logging::LogMessage(file, line).stream() << msg;
}
bool GetMimeTypeFromExtension(const std::wstring &ext, std::string *mime_type) {
return net::GetMimeTypeFromExtension(ext, mime_type);
}
bool GetMimeTypeFromFile(const std::wstring &file_path,
std::string *mime_type) {
return net::GetMimeTypeFromFile(file_path, mime_type);
}
bool GetPreferredExtensionForMimeType(const std::string& mime_type,
std::wstring* ext) {
return net::GetPreferredExtensionForMimeType(mime_type, ext);
}
std::string GetDataResource(int resource_id) {
if (resource_id == IDR_BROKENIMAGE) {
// Use webkit's broken image icon (16x16)
static unsigned char broken_image_data[] = {
0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x10, 0x00, 0x10, 0x00, 0xD5, 0x00,
0x00, 0x20, 0x68, 0xB0, 0x70, 0x98, 0xC0, 0x28, 0x78, 0xB8, 0x20, 0x70,
0xB8, 0x88, 0xB8, 0xD8, 0x78, 0x98, 0xC8, 0x28, 0x80, 0xC0, 0xF8, 0xF8,
0xF8, 0xF0, 0xF0, 0xF8, 0xE0, 0xE8, 0xF0, 0xD0, 0xE0, 0xF0, 0xB8, 0xD0,
0xE8, 0xC0, 0xD8, 0xE8, 0x98, 0xC0, 0xE0, 0x68, 0x90, 0xC0, 0x70, 0x90,
0xC0, 0x30, 0x80, 0xC0, 0x28, 0x88, 0xC0, 0x30, 0x78, 0xB8, 0x88, 0xB8,
0xE0, 0x78, 0xA0, 0xC8, 0x20, 0x70, 0xB0, 0x90, 0xA8, 0xD0, 0x88, 0xA8,
0xD0, 0x70, 0x98, 0xC8, 0x90, 0xB0, 0xD0, 0x80, 0xA0, 0xC8, 0x28, 0x88,
0xC8, 0x20, 0x78, 0xB8, 0x40, 0x90, 0xC8, 0x50, 0x98, 0xC8, 0x28, 0x78,
0xC0, 0x50, 0x90, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x06,
0x8F, 0xC0, 0x8C, 0x70, 0x48, 0x2C, 0x66, 0x2C, 0x87, 0xA4, 0x72, 0xB9,
0xB4, 0x20, 0x37, 0xD0, 0xA8, 0x14, 0x7A, 0xB0, 0x5C, 0x0E, 0x51, 0x83,
0x76, 0x1B, 0x3D, 0x5C, 0xAE, 0x91, 0x88, 0x76, 0x32, 0x59, 0x34, 0x3A,
0x86, 0xB0, 0x57, 0x73, 0xD8, 0x12, 0x12, 0x86, 0xCE, 0x21, 0xF1, 0xD1,
0x1E, 0x34, 0xEC, 0xAD, 0x87, 0x20, 0x80, 0x1C, 0x10, 0x02, 0x76, 0x78,
0x6D, 0x06, 0x1F, 0x02, 0x87, 0x0D, 0x0C, 0x20, 0x1C, 0x82, 0x14, 0x07,
0x87, 0x87, 0x1C, 0x20, 0x04, 0x1C, 0x95, 0x87, 0x07, 0x14, 0x05, 0x07,
0x95, 0x95, 0x03, 0x12, 0x12, 0x03, 0x9C, 0x1C, 0x07, 0x05, 0x18, 0x07,
0x03, 0xA8, 0x03, 0x15, 0x0A, 0x0A, 0x15, 0xA9, 0x03, 0x07, 0x18, 0x01,
0xA7, 0xA9, 0xAB, 0xAD, 0xAF, 0x07, 0x01, 0x0F, 0x07, 0x15, 0xBD, 0x15,
0x00, 0xC0, 0x00, 0xBE, 0x15, 0x07, 0x0F, 0x0E, 0xBC, 0xC3, 0xC9, 0xBD,
0x07, 0x0E, 0xC7, 0x4C, 0xCF, 0x49, 0xCD, 0xD2, 0xD3, 0xD4, 0xD2, 0x41,
0x00, 0x3B
};
return reinterpret_cast<char*>(broken_image_data);
} else if (resource_id == IDR_FEED_PREVIEW) {
// It is necessary to return a feed preview template that contains
// a {{URL}} substring where the feed URL should go; see the code
// that computes feed previews in feed_preview.cc:MakeFeedPreview.
// This fixes issue #932714.
return std::string("Feed preview for {{URL}}");
} else {
return std::string();
}
}
GlueBitmap GetBitmapResource(int resource_id) {
return NULL;
}
bool GetApplicationDirectory(std::wstring *path) {
return PathService::Get(base::DIR_EXE, path);
}
GURL GetInspectorURL() {
return GURL("cef-resource://inspector/inspector.html");
}
std::string GetUIResourceProtocol() {
return "cef-resource";
}
bool GetExeDirectory(std::wstring *path) {
return PathService::Get(base::DIR_EXE, path);
}
bool SpellCheckWord(const wchar_t* word, int word_len,
int* misspelling_start, int* misspelling_len) {
// Report all words being correctly spelled.
*misspelling_start = 0;
*misspelling_len = 0;
return true;
}
bool IsPluginRunningInRendererProcess() {
return true;
}
bool GetPluginFinderURL(std::string* plugin_finder_url) {
return false;
}
bool IsDefaultPluginEnabled() {
return false;
}
std::wstring GetWebKitLocale() {
return L"en-US";
}
std::string GetDocumentString(WebFrame* frame) {
WebFrameImpl* webFrameImpl = static_cast<WebFrameImpl*>(frame);
WebCore::Frame* core_frame = webFrameImpl->frame();
return StringToStdString(WebCore::createMarkup(core_frame->document()));
}
} // namespace webkit_glue

View File

@ -0,0 +1,24 @@
// Copyright (c) 2008 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 <string>
class WebFrame;
class WebView;
namespace webkit_glue {
// Return the HTML contents of a web frame as a string
std::string GetDocumentString(WebFrame* frame);
#if defined(OS_WIN)
// Capture a bitmap of the web view.
void CaptureWebViewBitmap(HWND mainWnd, WebView* webview, HBITMAP& bitmap,
SIZE& size);
// Save a bitmap image to file, providing optional alternative data in |lpBits|
BOOL SaveBitmapToFile(HBITMAP hBmp, HDC hDC, LPCTSTR file, LPBYTE lpBits);
#endif
} // namespace webkit_glue

View File

@ -0,0 +1,291 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "browser_webkit_glue.h"
#include <atlcore.h>
#include <atlbase.h>
#include <commdlg.h>
#include "base/compiler_specific.h"
#include "config.h"
#include "webkit_version.h"
MSVC_PUSH_WARNING_LEVEL(0);
#include "PlatformContextSkia.h"
MSVC_POP_WARNING();
#undef LOG
#include "base/gfx/gdi_util.h"
#include "base/logging.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webview.h"
#include "webkit/glue/plugins/plugin_list.h"
namespace webkit_glue {
std::wstring GetLocalizedString(int message_id) {
const ATLSTRINGRESOURCEIMAGE* image =
AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(),
message_id);
// TODO(cef): Need to provide strings for common resources.
if (!image) {
NOTREACHED();
return L"No string for this identifier!";
}
return std::wstring(image->achString, image->nLength);
}
HCURSOR LoadCursor(int cursor_id) {
return NULL;
}
bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
return NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins);
}
bool EnsureFontLoaded(HFONT font) {
return true;
}
bool DownloadUrl(const std::string& url, HWND caller_window) {
return false;
}
ScreenInfo GetScreenInfo(gfx::ViewHandle window) {
return GetScreenInfoHelper(window);
}
void CaptureWebViewBitmap(HWND mainWnd, WebView* webview, HBITMAP& bitmap, SIZE& size)
{
gfx::Size webSize = webview->GetSize();
size.cx = webSize.width();
size.cy = webSize.height();
gfx::PlatformCanvasWin canvas(size.cx, size.cy, true);
canvas.drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode);
PlatformContextSkia context(&canvas);
gfx::Rect rect(size.cx, size.cy);
webview->Layout();
webview->Paint(&canvas, rect);
HDC hRefDC = GetDC(mainWnd);
HDC hDC = CreateCompatibleDC(hRefDC);
bitmap = CreateCompatibleBitmap(hRefDC, size.cx, size.cy);
DCHECK(bitmap != NULL);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, bitmap);
// Create a BMP v4 header that we can serialize.
BITMAPV4HEADER bitmap_header;
gfx::CreateBitmapV4Header(size.cx, size.cy, &bitmap_header);
const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true);
SkAutoLockPixels src_lock(src_bmp);
int retval = StretchDIBits(hDC,
0,
0,
size.cx, size.cy,
0, 0,
size.cx, size.cy,
src_bmp.getPixels(),
reinterpret_cast<BITMAPINFO*>(&bitmap_header),
DIB_RGB_COLORS,
SRCCOPY);
DCHECK(retval != GDI_ERROR);
SelectObject(hDC, hOldBmp);
DeleteDC(hDC);
ReleaseDC(mainWnd, hRefDC);
}
static PBITMAPINFO BmpCreateInfo(HBITMAP hBmp)
{
BITMAP bmp;
PBITMAPINFO pbmi;
WORD cClrBits;
// Retrieve the bitmap color format, width, and height.
if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) {
NOTREACHED();
return NULL;
}
// Convert the color format to a count of bits.
cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
if (cClrBits == 1) {
cClrBits = 1;
} else if (cClrBits <= 4) {
cClrBits = 4;
} else if (cClrBits <= 8) {
cClrBits = 8;
} else if (cClrBits <= 16) {
cClrBits = 16;
} else if (cClrBits <= 24) {
cClrBits = 24;
} else {
cClrBits = 32;
}
// Allocate memory for the BITMAPINFO structure. (This structure
// contains a BITMAPINFOHEADER structure and an array of RGBQUAD
// data structures.)
if (cClrBits != 24) {
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits));
} else { // There is no RGBQUAD array for the 24-bit-per-pixel format.
pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
}
// Initialize the fields in the BITMAPINFO structure.
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (cClrBits < 24) {
pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
}
// If the bitmap is not compressed, set the BI_RGB flag.
pbmi->bmiHeader.biCompression = BI_RGB;
// Compute the number of bytes in the array of color
// indices and store the result in biSizeImage.
// For Windows NT, the width must be DWORD aligned unless
// the bitmap is RLE compressed. This example shows this.
// For Windows 95/98/Me, the width must be WORD aligned unless the
// bitmap is RLE compressed.
pbmi->bmiHeader.biSizeImage =
((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
* pbmi->bmiHeader.biHeight;
// Set biClrImportant to 0, indicating that all of the
// device colors are important.
pbmi->bmiHeader.biClrImportant = 0;
return pbmi;
}
static BOOL BmpSaveFile(LPCTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP,
HDC hDC, LPBYTE lpBits = NULL)
{
HANDLE hf = INVALID_HANDLE_VALUE; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp;
BOOL ret = FALSE;
BOOL bitsAlloc = FALSE;
pbih = (PBITMAPINFOHEADER) pbi;
if(!lpBits) {
// The bits have not been provided, so retrieve from the bitmap file
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits) {
// Memory could not be allocated
NOTREACHED();
return FALSE;
}
bitsAlloc = TRUE;
// Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS)) {
NOTREACHED();
goto end;
}
}
// Create the bitmap file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE) {
// Could not create the bitmap file
NOTREACHED();
goto end;
}
hdr.bfType = 0x4d42; // 0x42 = "B", 0x4d = "M"
// Compute the size of the entire file.
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
// Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof (RGBQUAD);
// Copy the BITMAPFILEHEADER into the bitmap file.
if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD) &dwTmp, NULL)) {
// Could not write bitmap file header to file
NOTREACHED();
goto end;
}
// Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, NULL)) {
// Could not write bitmap info header to file
NOTREACHED();
goto end;
}
// Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) {
// Could not write bitmap data to file
NOTREACHED();
goto end;
}
ret = TRUE;
end:
// Close the bitmap file.
if(hf != INVALID_HANDLE_VALUE) {
CloseHandle(hf);
if(!ret)
DeleteFile(pszFile);
}
if(bitsAlloc)
{
// Free memory.
GlobalFree((HGLOBAL)lpBits);
}
return ret;
}
BOOL SaveBitmapToFile(HBITMAP hBmp, HDC hDC, LPCTSTR file, LPBYTE lpBits)
{
PBITMAPINFO pbmi = BmpCreateInfo(hBmp);
BOOL ret = FALSE;
if(pbmi) {
ret = BmpSaveFile(file, pbmi, hBmp, hDC, lpBits);
LocalFree(pbmi);
}
return ret;
}
} // namespace webkit_glue

View File

@ -0,0 +1,653 @@
// Copyright (c) 2008 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.
// This file contains the implementation of BrowserWebViewDelegate, which serves
// as the WebViewDelegate for the BrowserWebHost. The host is expected to
// have initialized a MessageLoop before these methods are called.
#include "precompiled_libcef.h"
#include "browser_webview_delegate.h"
#include "browser_impl.h"
#include "browser_navigation_controller.h"
#include "context.h"
#include "request_impl.h"
#include "base/file_util.h"
#include "base/gfx/point.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/trace_event.h"
#include "net/base/net_errors.h"
#include "webkit/glue/webdatasource.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/weberror.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webpreferences.h"
#include "webkit/glue/weburlrequest.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webview.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/window_open_disposition.h"
#if defined(OS_WIN)
// TODO(port): make these files work everywhere.
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "browser_drag_delegate.h"
#include "browser_drop_delegate.h"
#endif
namespace {
int next_page_id_ = 1;
} // namespace
// WebViewDelegate -----------------------------------------------------------
WebView* BrowserWebViewDelegate::CreateWebView(WebView* webview,
bool user_gesture) {
CefRefPtr<CefBrowserImpl> browser =
browser_->UIT_CreatePopupWindow(std::wstring());
return browser.get() ? browser->UIT_GetWebView() : NULL;
}
WebWidget* BrowserWebViewDelegate::CreatePopupWidget(WebView* webview,
bool focus_on_show) {
return browser_->UIT_CreatePopupWidget(webview);
}
void BrowserWebViewDelegate::OpenURL(WebView* webview, const GURL& url,
const GURL& referrer,
WindowOpenDisposition disposition) {
DCHECK_NE(disposition, CURRENT_TAB); // No code for this
if (disposition == SUPPRESS_OPEN)
return;
CefRefPtr<CefBrowserImpl> browser =
browser_->UIT_CreatePopupWindow(UTF8ToWide(url.spec()));
if(browser.get())
browser->UIT_Show(browser->UIT_GetWebView(), disposition);
}
void BrowserWebViewDelegate::DidStartLoading(WebView* webview) {
// clear the title so we can tell if it wasn't provided by the page
browser_->UIT_SetTitle(std::wstring());
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// Notify the handler that loading has started
handler->HandleLoadStart(browser_);
}
}
void BrowserWebViewDelegate::DidStopLoading(WebView* webview) {
if(browser_->UIT_GetTitle().empty()) {
// no title was provided by the page, so send a blank string to the client
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// Notify the handler of a page title change
handler->HandleTitleChange(browser_, browser_->UIT_GetTitle());
}
}
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// Notify the handler that loading has ended
handler->HandleLoadEnd(browser_);
}
}
void BrowserWebViewDelegate::WindowObjectCleared(WebFrame* webframe) {
browser_->UIT_BindJSObjectsToWindow(webframe);
}
WindowOpenDisposition BrowserWebViewDelegate::DispositionForNavigationAction(
WebView* webview,
WebFrame* frame,
const WebRequest* request,
WebNavigationType type,
WindowOpenDisposition disposition,
bool is_redirect) {
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// Gather browse request information
CefRefPtr<CefRequest> req(CefRequest::CreateRequest());
req->SetURL(UTF8ToWide(request->GetURL().spec()));
req->SetMethod(UTF8ToWide(request->GetHttpMethod()));
if(request->HasUploadData()) {
scoped_refptr<net::UploadData> data(new net::UploadData());
request->GetUploadData(data.get());
CefRefPtr<CefPostData> postdata(CefPostData::CreatePostData());
static_cast<CefPostDataImpl*>(postdata.get())->Set(*data.get());
req->SetPostData(postdata);
}
WebRequest::HeaderMap map;
request->GetHttpHeaders(&map);
if(map.size() > 0)
static_cast<CefRequestImpl*>(req.get())->SetHeaderMap(map);
// Notify the handler of a browse request
CefHandler::RetVal rv = handler->HandleBeforeBrowse(browser_, req,
(CefHandler::NavType)type, is_redirect);
if(rv == CefHandler::RV_HANDLED)
return IGNORE_ACTION;
}
if (is_custom_policy_delegate_) {
std::wstring frame_name = frame->GetName();
printf("Policy delegate: attempt to load %s\n",
request->GetURL().spec().c_str());
return IGNORE_ACTION;
} else {
return WebViewDelegate::DispositionForNavigationAction(
webview, frame, request, type, disposition, is_redirect);
}
}
void BrowserWebViewDelegate::SetCustomPolicyDelegate(bool isCustom) {
is_custom_policy_delegate_ = isCustom;
}
void BrowserWebViewDelegate::AssignIdentifierToRequest(WebView* webview,
uint32 identifier,
const WebRequest& request) {
}
void BrowserWebViewDelegate::WillSendRequest(WebView* webview,
uint32 identifier,
WebRequest* request) {
}
void BrowserWebViewDelegate::DidFinishLoading(WebView* webview,
uint32 identifier) {
}
void BrowserWebViewDelegate::DidFailLoadingWithError(WebView* webview,
uint32 identifier,
const WebError& error) {
}
void BrowserWebViewDelegate::DidStartProvisionalLoadForFrame(
WebView* webview,
WebFrame* frame,
NavigationGesture gesture) {
if (!top_loading_frame_) {
top_loading_frame_ = frame;
}
UpdateAddressBar(webview);
}
void BrowserWebViewDelegate::DidReceiveServerRedirectForProvisionalLoadForFrame(
WebView* webview,
WebFrame* frame) {
UpdateAddressBar(webview);
}
void BrowserWebViewDelegate::DidFailProvisionalLoadWithError(
WebView* webview,
const WebError& error,
WebFrame* frame) {
LocationChangeDone(frame->GetProvisionalDataSource());
// error codes are defined in net\base\net_error_list.h
// Don't display an error page if this is simply a cancelled load. Aside
// from being dumb, WebCore doesn't expect it and it will cause a crash.
if (error.GetErrorCode() == net::ERR_ABORTED)
return;
const WebRequest& failed_request =
frame->GetProvisionalDataSource()->GetRequest();
BrowserExtraRequestData* extra_data =
static_cast<BrowserExtraRequestData*>(failed_request.GetExtraData());
bool replace = extra_data && extra_data->pending_page_id != -1;
scoped_ptr<WebRequest> request(failed_request.Clone());
request->SetURL(GURL("cef-error:"));
std::string error_text;
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// give the handler an opportunity to generate a custom error message
std::wstring error_str;
CefHandler::RetVal rv = handler->HandleLoadError(browser_,
static_cast<CefHandler::ErrorCode>(error.GetErrorCode()),
UTF8ToWide(error.GetFailedURL().spec()), error_str);
if(rv == CefHandler::RV_HANDLED && !error_str.empty())
error_text = WideToUTF8(error_str);
} else {
error_text = StringPrintf("Error loading url: %d", error.GetErrorCode());
}
frame->LoadAlternateHTMLString(request.get(), error_text,
error.GetFailedURL(), replace);
}
void BrowserWebViewDelegate::DidCommitLoadForFrame(WebView* webview,
WebFrame* frame,
bool is_new_navigation) {
UpdateForCommittedLoad(frame, is_new_navigation);
}
void BrowserWebViewDelegate::DidReceiveTitle(WebView* webview,
const std::wstring& title,
WebFrame* frame) {
browser_->UIT_SetTitle(title);
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// Notify the handler of a page title change
handler->HandleTitleChange(browser_, title);
}
}
void BrowserWebViewDelegate::DidFinishLoadForFrame(WebView* webview,
WebFrame* frame) {
UpdateAddressBar(webview);
LocationChangeDone(frame->GetDataSource());
}
void BrowserWebViewDelegate::DidFailLoadWithError(WebView* webview,
const WebError& error,
WebFrame* frame) {
LocationChangeDone(frame->GetDataSource());
}
void BrowserWebViewDelegate::DidFinishDocumentLoadForFrame(WebView* webview,
WebFrame* frame) {
}
void BrowserWebViewDelegate::DidHandleOnloadEventsForFrame(WebView* webview,
WebFrame* frame) {
}
void BrowserWebViewDelegate::DidChangeLocationWithinPageForFrame(
WebView* webview, WebFrame* frame, bool is_new_navigation) {
UpdateForCommittedLoad(frame, is_new_navigation);
}
void BrowserWebViewDelegate::DidReceiveIconForFrame(WebView* webview,
WebFrame* frame) {
}
void BrowserWebViewDelegate::WillPerformClientRedirect(WebView* webview,
WebFrame* frame,
const std::wstring& dest_url,
unsigned int delay_seconds,
unsigned int fire_date) {
}
void BrowserWebViewDelegate::DidCancelClientRedirect(WebView* webview,
WebFrame* frame) {
}
void BrowserWebViewDelegate::AddMessageToConsole(WebView* webview,
const std::wstring& message,
unsigned int line_no,
const std::wstring& source_id) {
logging::LogMessage("CONSOLE", 0).stream() << "\""
<< message.c_str()
<< ",\" source: "
<< source_id.c_str()
<< "("
<< line_no
<< ")";
}
void BrowserWebViewDelegate::RunJavaScriptAlert(WebView* webview,
const std::wstring& message) {
CefHandler::RetVal rv = CefHandler::RV_CONTINUE;
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get())
rv = handler->HandleJSAlert(browser_, message);
if(rv != CefHandler::RV_HANDLED)
ShowJavaScriptAlert(webview, message);
}
bool BrowserWebViewDelegate::RunJavaScriptConfirm(WebView* webview,
const std::wstring& message) {
CefHandler::RetVal rv = CefHandler::RV_CONTINUE;
bool retval = false;
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get())
rv = handler->HandleJSConfirm(browser_, message, retval);
if(rv != CefHandler::RV_HANDLED)
retval = ShowJavaScriptConfirm(webview, message);
return retval;
}
bool BrowserWebViewDelegate::RunJavaScriptPrompt(WebView* webview,
const std::wstring& message, const std::wstring& default_value,
std::wstring* result) {
CefHandler::RetVal rv = CefHandler::RV_CONTINUE;
bool retval = false;
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
rv = handler->HandleJSPrompt(browser_, message, default_value,
retval, *result);
}
if(rv != CefHandler::RV_HANDLED)
retval = ShowJavaScriptPrompt(webview, message, default_value, result);
return retval;
}
void BrowserWebViewDelegate::StartDragging(WebView* webview,
const WebDropData& drop_data) {
#if defined(OS_WIN)
// TODO(port): make this work on all platforms.
if (!drag_delegate_) {
drag_delegate_ = new BrowserDragDelegate(
browser_->UIT_GetWebViewWndHandle(),
browser_->UIT_GetWebView());
}
// TODO(tc): Drag and drop is disabled in the test shell because we need
// to be able to convert from WebDragData to an IDataObject.
//const DWORD ok_effect = DROPEFFECT_COPY | DROPEFFECT_LINK | DROPEFFECT_MOVE;
//DWORD effect;
//HRESULT res = DoDragDrop(drop_data.data_object, drag_delegate_.get(),
// ok_effect, &effect);
//DCHECK(DRAGDROP_S_DROP == res || DRAGDROP_S_CANCEL == res);
webview->DragSourceSystemDragEnded();
#endif
}
// The output from these methods in non-interactive mode should match that
// expected by the layout tests. See EditingDelegate.m in DumpRenderTree.
bool BrowserWebViewDelegate::ShouldBeginEditing(WebView* webview,
std::wstring range) {
return browser_->UIT_AllowEditing();
}
bool BrowserWebViewDelegate::ShouldEndEditing(WebView* webview,
std::wstring range) {
return browser_->UIT_AllowEditing();
}
bool BrowserWebViewDelegate::ShouldInsertNode(WebView* webview,
std::wstring node,
std::wstring range,
std::wstring action) {
return browser_->UIT_AllowEditing();
}
bool BrowserWebViewDelegate::ShouldInsertText(WebView* webview,
std::wstring text,
std::wstring range,
std::wstring action) {
return browser_->UIT_AllowEditing();
}
bool BrowserWebViewDelegate::ShouldChangeSelectedRange(WebView* webview,
std::wstring fromRange,
std::wstring toRange,
std::wstring affinity,
bool stillSelecting) {
return browser_->UIT_AllowEditing();
}
bool BrowserWebViewDelegate::ShouldDeleteRange(WebView* webview,
std::wstring range) {
return browser_->UIT_AllowEditing();
}
bool BrowserWebViewDelegate::ShouldApplyStyle(WebView* webview,
std::wstring style,
std::wstring range) {
return browser_->UIT_AllowEditing();
}
bool BrowserWebViewDelegate::SmartInsertDeleteEnabled() {
return true;
}
void BrowserWebViewDelegate::DidBeginEditing() {
}
void BrowserWebViewDelegate::DidChangeSelection() {
}
void BrowserWebViewDelegate::DidChangeContents() {
}
void BrowserWebViewDelegate::DidEndEditing() {
}
WebHistoryItem* BrowserWebViewDelegate::GetHistoryEntryAtOffset(int offset) {
BrowserNavigationEntry* entry = static_cast<BrowserNavigationEntry*>(
browser_->UIT_GetNavigationController()->GetEntryAtOffset(offset));
if (!entry)
return NULL;
return entry->GetHistoryItem();
}
int BrowserWebViewDelegate::GetHistoryBackListCount() {
int current_index =
browser_->UIT_GetNavigationController()->GetLastCommittedEntryIndex();
return current_index;
}
int BrowserWebViewDelegate::GetHistoryForwardListCount() {
int current_index =
browser_->UIT_GetNavigationController()->GetLastCommittedEntryIndex();
return browser_->UIT_GetNavigationController()->GetEntryCount()
- current_index - 1;
}
void BrowserWebViewDelegate::SetUserStyleSheetEnabled(bool is_enabled) {
WebPreferences* prefs = _Context->GetWebPreferences();
prefs->user_style_sheet_enabled = is_enabled;
browser_->UIT_GetWebView()->SetPreferences(*prefs);
}
void BrowserWebViewDelegate::SetUserStyleSheetLocation(const GURL& location) {
WebPreferences* prefs = _Context->GetWebPreferences();
prefs->user_style_sheet_enabled = true;
prefs->user_style_sheet_location = location;
browser_->UIT_GetWebView()->SetPreferences(*prefs);
}
// WebWidgetDelegate ---------------------------------------------------------
gfx::ViewHandle BrowserWebViewDelegate::GetContainingWindow(WebWidget* webwidget) {
if (WebWidgetHost* host = GetHostForWidget(webwidget))
return host->window_handle();
return NULL;
}
void BrowserWebViewDelegate::DidInvalidateRect(WebWidget* webwidget,
const gfx::Rect& rect) {
if (WebWidgetHost* host = GetHostForWidget(webwidget))
host->DidInvalidateRect(rect);
}
void BrowserWebViewDelegate::DidScrollRect(WebWidget* webwidget, int dx, int dy,
const gfx::Rect& clip_rect) {
if (WebWidgetHost* host = GetHostForWidget(webwidget))
host->DidScrollRect(dx, dy, clip_rect);
}
void BrowserWebViewDelegate::Focus(WebWidget* webwidget) {
if (WebWidgetHost* host = GetHostForWidget(webwidget))
browser_->UIT_SetFocus(host, true);
}
void BrowserWebViewDelegate::Blur(WebWidget* webwidget) {
if (WebWidgetHost* host = GetHostForWidget(webwidget))
browser_->UIT_SetFocus(host, false);
}
void BrowserWebViewDelegate::DidMove(WebWidget* webwidget,
const WebPluginGeometry& move) {
#if defined(OS_WIN)
// TODO(port): add me once plugins work.
WebPluginDelegateImpl::MoveWindow(
move.window, move.window_rect, move.clip_rect, move.cutout_rects,
move.visible);
#endif
}
bool BrowserWebViewDelegate::IsHidden() {
return false;
}
void BrowserWebViewDelegate::RegisterDragDrop() {
#if defined(OS_WIN)
// TODO(port): add me once drag and drop works.
DCHECK(!drop_delegate_);
drop_delegate_ = new BrowserDropDelegate(browser_->UIT_GetWebViewWndHandle(),
browser_->UIT_GetWebView());
#endif
}
// Private methods -----------------------------------------------------------
void BrowserWebViewDelegate::UpdateAddressBar(WebView* webView) {
/*
WebFrame* mainFrame = webView->UIT_GetMainFrame();
WebDataSource* dataSource = mainFrame->GetDataSource();
if (!dataSource)
dataSource = mainFrame->GetProvisionalDataSource();
if (!dataSource)
return;
GURL gUrl = dataSource->GetRequest().GetMainDocumentURL();
*/
}
void BrowserWebViewDelegate::LocationChangeDone(WebDataSource* data_source) {
if (data_source->GetWebFrame() == top_loading_frame_)
top_loading_frame_ = NULL;
}
WebWidgetHost* BrowserWebViewDelegate::GetHostForWidget(WebWidget* webwidget) {
if (webwidget == browser_->UIT_GetWebView())
return browser_->UIT_GetWebViewHost();
if (webwidget == browser_->UIT_GetPopup())
return browser_->UIT_GetPopupHost();
return NULL;
}
void BrowserWebViewDelegate::UpdateForCommittedLoad(WebFrame* frame,
bool is_new_navigation) {
WebView* webview = browser_->UIT_GetWebView();
// Code duplicated from RenderView::DidCommitLoadForFrame.
const WebRequest& request =
webview->GetMainFrame()->GetDataSource()->GetRequest();
BrowserExtraRequestData* extra_data =
static_cast<BrowserExtraRequestData*>(request.GetExtraData());
if (is_new_navigation) {
// New navigation.
UpdateSessionHistory(frame);
page_id_ = next_page_id_++;
} else if (extra_data && extra_data->pending_page_id != -1 &&
!extra_data->request_committed) {
// This is a successful session history navigation!
UpdateSessionHistory(frame);
page_id_ = extra_data->pending_page_id;
}
// Don't update session history multiple times.
if (extra_data)
extra_data->request_committed = true;
UpdateURL(frame);
}
void BrowserWebViewDelegate::UpdateURL(WebFrame* frame) {
WebDataSource* ds = frame->GetDataSource();
DCHECK(ds);
const WebRequest& request = ds->GetRequest();
// Type is unused.
scoped_ptr<BrowserNavigationEntry> entry(new BrowserNavigationEntry);
// Bug 654101: the referrer will be empty on https->http transitions. It
// would be nice if we could get the real referrer from somewhere.
entry->SetPageID(page_id_);
if (ds->HasUnreachableURL()) {
entry->SetURL(GURL(ds->GetUnreachableURL()));
} else {
entry->SetURL(GURL(request.GetURL()));
}
std::wstring url = UTF8ToWide(entry->GetURL().spec().c_str());
browser_->SetURL(url);
if(frame->GetView()->GetMainFrame() == frame) {
// only send address changes that originate from the main frame
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// Notify the handler of an address change
handler->HandleAddressChange(browser_, url);
}
}
browser_->UIT_GetNavigationController()->DidNavigateToEntry(entry.release());
last_page_id_updated_ = std::max(last_page_id_updated_, page_id_);
}
void BrowserWebViewDelegate::UpdateSessionHistory(WebFrame* frame) {
// If we have a valid page ID at this point, then it corresponds to the page
// we are navigating away from. Otherwise, this is the first navigation, so
// there is no past session history to record.
if (page_id_ == -1)
return;
BrowserNavigationEntry* entry = static_cast<BrowserNavigationEntry*>(
browser_->UIT_GetNavigationController()->GetEntryWithPageID(page_id_));
if (!entry)
return;
GURL url;
std::wstring title;
std::string state;
if (!browser_->UIT_GetWebView()->GetMainFrame()->
GetPreviousState(&url, &title, &state))
return;
entry->SetURL(url);
entry->SetTitle(title);
entry->SetContentState(state);
}
std::wstring BrowserWebViewDelegate::GetFrameDescription(WebFrame* webframe) {
std::wstring name = webframe->GetName();
if (webframe == browser_->UIT_GetWebView()->GetMainFrame()) {
if (name.length())
return L"main frame \"" + name + L"\"";
else
return L"main frame";
} else {
if (name.length())
return L"frame \"" + name + L"\"";
else
return L"frame (anonymous)";
}
}

View File

@ -0,0 +1,280 @@
// Copyright (c) 2008 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.
// BrowserWebViewDelegate class:
// This class implements the WebViewDelegate methods for the test shell. One
// instance is owned by each CefBrowser.
#ifndef _BROWSER_WEBVIEW_DELEGATE_H
#define _BROWSER_WEBVIEW_DELEGATE_H
#include "build/build_config.h"
#include <map>
#if defined(OS_LINUX)
#include <gdk/gdkcursor.h>
#endif
#include "base/basictypes.h"
#include "base/ref_counted.h"
#include "webkit/glue/webview_delegate.h"
#include "webkit/glue/webwidget_delegate.h"
#if defined(OS_WIN)
#include "browser_drag_delegate.h"
#include "browser_drop_delegate.h"
#endif
class CefBrowserImpl;
struct WebPreferences;
class GURL;
class WebDataSource;
class WebWidgetHost;
class BrowserWebViewDelegate : public base::RefCounted<BrowserWebViewDelegate>,
public WebViewDelegate {
public:
BrowserWebViewDelegate(CefBrowserImpl* shell)
: is_custom_policy_delegate_(false),
browser_(shell),
top_loading_frame_(NULL),
page_id_(-1),
last_page_id_updated_(-1)
#if defined(OS_WIN)
, custom_cursor_(NULL)
#elif defined(OS_LINUX)
, cursor_type_(GDK_X_CURSOR)
#endif
{
}
virtual ~BrowserWebViewDelegate();
// WebViewDelegate
virtual WebView* CreateWebView(WebView* webview, bool user_gesture);
virtual WebWidget* CreatePopupWidget(WebView* webview, bool focus_on_show);
virtual WebPluginDelegate* CreatePluginDelegate(
WebView* webview,
const GURL& url,
const std::string& mime_type,
const std::string& clsid,
std::string* actual_mime_type);
virtual void OpenURL(WebView* webview,
const GURL& url,
const GURL& referrer,
WindowOpenDisposition disposition);
virtual void RunJavaScriptAlert(WebView* webview,
const std::wstring& message);
virtual bool RunJavaScriptConfirm(WebView* webview,
const std::wstring& message);
virtual bool RunJavaScriptPrompt(WebView* webview,
const std::wstring& message,
const std::wstring& default_value,
std::wstring* result);
virtual void AddMessageToConsole(WebView* webview,
const std::wstring& message,
unsigned int line_no,
const std::wstring& source_id);
virtual void StartDragging(WebView* webview,
const WebDropData& drop_data);
virtual void ShowContextMenu(WebView* webview,
ContextNode::Type type,
int x,
int y,
const GURL& link_url,
const GURL& image_url,
const GURL& page_url,
const GURL& frame_url,
const std::wstring& selection_text,
const std::wstring& misspelled_word,
int edit_flags,
const std::string& security_info);
virtual void DidStartProvisionalLoadForFrame(
WebView* webview,
WebFrame* frame,
NavigationGesture gesture);
virtual void DidReceiveServerRedirectForProvisionalLoadForFrame(
WebView* webview, WebFrame* frame);
virtual void DidFailProvisionalLoadWithError(WebView* webview,
const WebError& error,
WebFrame* frame);
virtual void DidCommitLoadForFrame(WebView* webview, WebFrame* frame,
bool is_new_navigation);
virtual void DidReceiveTitle(WebView* webview,
const std::wstring& title,
WebFrame* frame);
virtual void DidFinishDocumentLoadForFrame(WebView* webview,
WebFrame* frame);
virtual void DidHandleOnloadEventsForFrame(WebView* webview,
WebFrame* frame);
virtual void DidChangeLocationWithinPageForFrame(WebView* webview,
WebFrame* frame,
bool is_new_navigation);
virtual void DidReceiveIconForFrame(WebView* webview, WebFrame* frame);
virtual void WillPerformClientRedirect(WebView* webview,
WebFrame* frame,
const std::wstring& dest_url,
unsigned int delay_seconds,
unsigned int fire_date);
virtual void DidCancelClientRedirect(WebView* webview,
WebFrame* frame);
virtual void DidFinishLoadForFrame(WebView* webview, WebFrame* frame);
virtual void DidFailLoadWithError(WebView* webview,
const WebError& error,
WebFrame* forFrame);
virtual void AssignIdentifierToRequest(WebView* webview,
uint32 identifier,
const WebRequest& request);
virtual void WillSendRequest(WebView* webview,
uint32 identifier,
WebRequest* request);
virtual void DidFinishLoading(WebView* webview, uint32 identifier);
virtual void DidFailLoadingWithError(WebView* webview,
uint32 identifier,
const WebError& error);
virtual bool ShouldBeginEditing(WebView* webview, std::wstring range);
virtual bool ShouldEndEditing(WebView* webview, std::wstring range);
virtual bool ShouldInsertNode(WebView* webview,
std::wstring node,
std::wstring range,
std::wstring action);
virtual bool ShouldInsertText(WebView* webview,
std::wstring text,
std::wstring range,
std::wstring action);
virtual bool ShouldChangeSelectedRange(WebView* webview,
std::wstring fromRange,
std::wstring toRange,
std::wstring affinity,
bool stillSelecting);
virtual bool ShouldDeleteRange(WebView* webview, std::wstring range);
virtual bool ShouldApplyStyle(WebView* webview,
std::wstring style,
std::wstring range);
virtual bool SmartInsertDeleteEnabled();
virtual void DidBeginEditing();
virtual void DidChangeSelection();
virtual void DidChangeContents();
virtual void DidEndEditing();
virtual void DidStartLoading(WebView* webview);
virtual void DidStopLoading(WebView* webview);
virtual void WindowObjectCleared(WebFrame* webframe);
virtual WindowOpenDisposition DispositionForNavigationAction(
WebView* webview,
WebFrame* frame,
const WebRequest* request,
WebNavigationType type,
WindowOpenDisposition disposition,
bool is_redirect);
void SetCustomPolicyDelegate(bool isCustom);
virtual WebHistoryItem* GetHistoryEntryAtOffset(int offset);
virtual int GetHistoryBackListCount();
virtual int GetHistoryForwardListCount();
// WebWidgetDelegate
virtual gfx::ViewHandle GetContainingWindow(WebWidget* webwidget);
virtual void DidInvalidateRect(WebWidget* webwidget, const gfx::Rect& rect);
virtual void DidScrollRect(WebWidget* webwidget, int dx, int dy,
const gfx::Rect& clip_rect);
virtual void Show(WebWidget* webview, WindowOpenDisposition disposition);
virtual void CloseWidgetSoon(WebWidget* webwidget);
virtual void Focus(WebWidget* webwidget);
virtual void Blur(WebWidget* webwidget);
virtual void SetCursor(WebWidget* webwidget,
const WebCursor& cursor);
virtual void GetWindowRect(WebWidget* webwidget, gfx::Rect* rect);
virtual void SetWindowRect(WebWidget* webwidget, const gfx::Rect& rect);
virtual void GetRootWindowRect(WebWidget *,gfx::Rect *);
virtual void GetRootWindowResizerRect(WebWidget* webwidget, gfx::Rect* rect);
virtual void DidMove(WebWidget* webwidget, const WebPluginGeometry& move);
virtual void RunModal(WebWidget* webwidget);
virtual bool IsHidden();
virtual void AddRef() {
base::RefCounted<BrowserWebViewDelegate>::AddRef();
}
virtual void Release() {
base::RefCounted<BrowserWebViewDelegate>::Release();
}
// Additional accessors
WebFrame* top_loading_frame() { return top_loading_frame_; }
#if defined(OS_WIN)
IDropTarget* drop_delegate() { return drop_delegate_.get(); }
IDropSource* drag_delegate() { return drag_delegate_.get(); }
#endif
// Methods for modifying WebPreferences
void SetUserStyleSheetEnabled(bool is_enabled);
void SetUserStyleSheetLocation(const GURL& location);
// Sets the webview as a drop target.
void RegisterDragDrop();
CefBrowserImpl* GetBrowser() { return browser_; }
protected:
// Called when the URL of the page changes.
void UpdateAddressBar(WebView* webView);
// Default handling of JavaScript messages.
void ShowJavaScriptAlert(WebView* webview, const std::wstring& message);
bool ShowJavaScriptConfirm(WebView* webview, const std::wstring& message);
bool ShowJavaScriptPrompt(WebView* webview, const std::wstring& message,
const std::wstring& default_value, std::wstring* result);
// In the Mac code, this is called to trigger the end of a test after the
// page has finished loading. From here, we can generate the dump for the
// test.
void LocationChangeDone(WebDataSource* data_source);
WebWidgetHost* GetHostForWidget(WebWidget* webwidget);
void UpdateForCommittedLoad(WebFrame* webframe, bool is_new_navigation);
void UpdateURL(WebFrame* frame);
void UpdateSessionHistory(WebFrame* frame);
// Get a string suitable for dumping a frame to the console.
std::wstring GetFrameDescription(WebFrame* webframe);
private:
// Causes navigation actions just printout the intended navigation instead
// of taking you to the page. This is used for cases like mailto, where you
// don't actually want to open the mail program.
bool is_custom_policy_delegate_;
// Non-owning pointer. The delegate is owned by the host.
CefBrowserImpl* browser_;
// This is non-NULL IFF a load is in progress.
WebFrame* top_loading_frame_;
// For tracking session history. See RenderView.
int page_id_;
int last_page_id_updated_;
#if defined(OS_WIN)
HCURSOR custom_cursor_;
// Classes needed by drag and drop.
scoped_refptr<BrowserDragDelegate> drag_delegate_;
scoped_refptr<BrowserDropDelegate> drop_delegate_;
#endif
#if defined(OS_LINUX)
// The type of cursor the window is currently using.
// Used for judging whether a new SetCursor call is actually changing the
// cursor.
GdkCursorType cursor_type_;
#endif
DISALLOW_EVIL_CONSTRUCTORS(BrowserWebViewDelegate);
};
#endif // _BROWSER_WEBVIEW_DELEGATE_H

View File

@ -0,0 +1,354 @@
// Copyright (c) 2008 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.
// This file contains the implementation of BrowserWebViewDelegate, which serves
// as the WebViewDelegate for the BrowserWebHost. The host is expected to
// have initialized a MessageLoop before these methods are called.
#include "precompiled_libcef.h"
#include "browser_webview_delegate.h"
#include "browser_drag_delegate.h"
#include "browser_drop_delegate.h"
#include "browser_navigation_controller.h"
#include "browser_impl.h"
#include "context.h"
#include <objidl.h>
#include <shlobj.h>
#include <shlwapi.h>
#include "base/gfx/point.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/trace_event.h"
#include "net/base/net_errors.h"
#include "webkit/glue/webdatasource.h"
#include "webkit/glue/webdropdata.h"
#include "webkit/glue/weberror.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webpreferences.h"
#include "webkit/glue/weburlrequest.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webview.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/glue/window_open_disposition.h"
// WebViewDelegate -----------------------------------------------------------
BrowserWebViewDelegate::~BrowserWebViewDelegate() {
if (custom_cursor_)
DestroyIcon(custom_cursor_);
RevokeDragDrop(browser_->UIT_GetWebViewWndHandle());
}
WebPluginDelegate* BrowserWebViewDelegate::CreatePluginDelegate(
WebView* webview,
const GURL& url,
const std::string& mime_type,
const std::string& clsid,
std::string* actual_mime_type) {
HWND hwnd = GetContainingWindow(webview);
if (!hwnd)
return NULL;
bool allow_wildcard = true;
WebPluginInfo info;
if (!NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid,
allow_wildcard, &info,
actual_mime_type))
return NULL;
if (actual_mime_type && !actual_mime_type->empty())
return WebPluginDelegateImpl::Create(info.file, *actual_mime_type, hwnd);
else
return WebPluginDelegateImpl::Create(info.file, mime_type, hwnd);
}
void BrowserWebViewDelegate::Show(WebWidget* webwidget, WindowOpenDisposition) {
if (webwidget == browser_->UIT_GetWebView()) {
ShowWindow(browser_->UIT_GetMainWndHandle(), SW_SHOW);
UpdateWindow(browser_->UIT_GetMainWndHandle());
} else if (webwidget == browser_->UIT_GetPopup()) {
ShowWindow(browser_->UIT_GetPopupWndHandle(), SW_SHOW);
UpdateWindow(browser_->UIT_GetPopupWndHandle());
}
}
void BrowserWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) {
if (webwidget == browser_->UIT_GetWebView()) {
PostMessage(browser_->UIT_GetMainWndHandle(), WM_CLOSE, 0, 0);
} else if (webwidget == browser_->UIT_GetPopup()) {
browser_->UIT_ClosePopupWidget();
}
}
void BrowserWebViewDelegate::SetCursor(WebWidget* webwidget,
const WebCursor& cursor) {
if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
if (custom_cursor_) {
DestroyIcon(custom_cursor_);
custom_cursor_ = NULL;
}
if (cursor.IsCustom()) {
custom_cursor_ = cursor.GetCustomCursor();
host->SetCursor(custom_cursor_);
} else {
HINSTANCE mod_handle = GetModuleHandle(NULL);
host->SetCursor(cursor.GetCursor(mod_handle));
}
}
}
void BrowserWebViewDelegate::GetWindowRect(WebWidget* webwidget,
gfx::Rect* out_rect) {
if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
RECT rect;
::GetWindowRect(host->window_handle(), &rect);
*out_rect = gfx::Rect(rect);
}
}
void BrowserWebViewDelegate::SetWindowRect(WebWidget* webwidget,
const gfx::Rect& rect) {
if (webwidget == browser_->UIT_GetWebView()) {
// ignored
} else if (webwidget == browser_->UIT_GetPopup()) {
MoveWindow(browser_->UIT_GetPopupWndHandle(),
rect.x(), rect.y(), rect.width(), rect.height(), FALSE);
}
}
void BrowserWebViewDelegate::GetRootWindowRect(WebWidget* webwidget,
gfx::Rect* out_rect) {
if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
RECT rect;
HWND root_window = ::GetAncestor(host->window_handle(), GA_ROOT);
::GetWindowRect(root_window, &rect);
*out_rect = gfx::Rect(rect);
}
}
void BrowserWebViewDelegate::GetRootWindowResizerRect(WebWidget* webwidget,
gfx::Rect* out_rect) {
// Not necessary on Windows.
*out_rect = gfx::Rect();
}
void BrowserWebViewDelegate::RunModal(WebWidget* webwidget) {
Show(webwidget, NEW_WINDOW);
CefContext::BrowserList *list;
CefContext::BrowserList::const_iterator i;
_Context->Lock();
list = _Context->GetBrowserList();
i = list->begin();
for (; i != list->end(); ++i) {
if (i->get()->IsPopup())
EnableWindow(i->get()->UIT_GetMainWndHandle(), FALSE);
}
_Context->Unlock();
browser_->UIT_SetIsModal(true);
MessageLoop::current()->Run();
_Context->Lock();
list = _Context->GetBrowserList();
i = list->begin();
for (; i != list->end(); ++i)
EnableWindow(i->get()->UIT_GetMainWndHandle(), TRUE);
_Context->Unlock();
}
static void AddMenuItem(CefRefPtr<CefBrowser> browser, HMENU menu, int index,
CefHandler::MenuId id, const wchar_t* label,
bool enabled, std::list<std::wstring>& label_list)
{
std::wstring actual_label = label;
CefRefPtr<CefHandler> handler = browser->GetHandler();
if(handler.get()) {
// Let the handler change the label if desired
handler->HandleGetMenuLabel(browser, id, actual_label);
}
// store the label in a list to simplify memory management
label_list.push_back(actual_label);
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
mii.fType = MFT_STRING;
if(!enabled) {
mii.fMask |= MIIM_STATE;
mii.fState = MFS_GRAYED;
}
mii.wID = id;
mii.dwTypeData = const_cast<wchar_t*>(label_list.back().c_str());
InsertMenuItem(menu, index, TRUE, &mii);
}
static void AddMenuSeparator(HMENU menu, int index)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE;
mii.fType = MFT_SEPARATOR;
InsertMenuItem(menu, index, TRUE, &mii);
}
void BrowserWebViewDelegate::ShowContextMenu(WebView* webview,
ContextNode::Type type,
int x,
int y,
const GURL& link_url,
const GURL& image_url,
const GURL& page_url,
const GURL& frame_url,
const std::wstring& selection_text,
const std::wstring& misspelled_word,
int edit_flags,
const std::string& security_info) {
POINT screen_pt = { x, y };
MapWindowPoints(browser_->UIT_GetMainWndHandle(), HWND_DESKTOP,
&screen_pt, 1);
HMENU menu = NULL;
std::list<std::wstring> label_list;
// Enable recursive tasks on the message loop so we can get updates while
// the context menu is being displayed.
bool old_state = MessageLoop::current()->NestableTasksAllowed();
MessageLoop::current()->SetNestableTasksAllowed(true);
if(browser_->UIT_CanGoBack())
edit_flags |= CefHandler::CAN_GO_BACK;
if(browser_->UIT_CanGoForward())
edit_flags |= CefHandler::CAN_GO_FORWARD;
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if(handler.get()) {
// Gather menu information
CefHandler::MenuInfo menuInfo;
menuInfo.menuType = static_cast<CefHandler::MenuType>(type);
menuInfo.x = screen_pt.x;
menuInfo.y = screen_pt.y;
menuInfo.linkUrl = UTF8ToWide(link_url.spec().c_str()).c_str();
menuInfo.imageUrl = UTF8ToWide(image_url.spec().c_str()).c_str();
menuInfo.pageUrl = UTF8ToWide(page_url.spec().c_str()).c_str();
menuInfo.frameUrl = UTF8ToWide(frame_url.spec().c_str()).c_str();
menuInfo.selectionText = selection_text;
menuInfo.misspelledWord = misspelled_word;
menuInfo.editFlags = edit_flags;
menuInfo.securityInfo = security_info;
// Notify the handler that a context menu is requested
CefHandler::RetVal rv = handler->HandleBeforeMenu(browser_, menuInfo);
if(rv == CefHandler::RV_HANDLED)
goto end;
}
// Build the correct default context menu
switch(type) {
case ContextNode::EDITABLE:
menu = CreatePopupMenu();
AddMenuItem(browser_, menu, -1, CefHandler::ID_UNDO, L"Undo",
!!(edit_flags & ContextNode::CAN_UNDO), label_list);
AddMenuItem(browser_, menu, -1, CefHandler::ID_REDO, L"Redo",
!!(edit_flags & ContextNode::CAN_REDO), label_list);
AddMenuSeparator(menu, -1);
AddMenuItem(browser_, menu, -1, CefHandler::ID_CUT, L"Cut",
!!(edit_flags & ContextNode::CAN_CUT), label_list);
AddMenuItem(browser_, menu, -1, CefHandler::ID_COPY, L"Copy",
!!(edit_flags & ContextNode::CAN_COPY), label_list);
AddMenuItem(browser_, menu, -1, CefHandler::ID_PASTE, L"Paste",
!!(edit_flags & ContextNode::CAN_PASTE), label_list);
AddMenuItem(browser_, menu, -1, CefHandler::ID_DELETE, L"Delete",
!!(edit_flags & ContextNode::CAN_DELETE), label_list);
AddMenuSeparator(menu, -1);
AddMenuItem(browser_, menu, -1, CefHandler::ID_SELECTALL, L"Select All",
!!(edit_flags & ContextNode::CAN_SELECT_ALL), label_list);
break;
case ContextNode::SELECTION:
menu = CreatePopupMenu();
AddMenuItem(browser_, menu, -1, CefHandler::ID_COPY, L"Copy",
!!(edit_flags & ContextNode::CAN_COPY), label_list);
break;
case ContextNode::PAGE:
case ContextNode::FRAME:
menu = CreatePopupMenu();
AddMenuItem(browser_, menu, -1, CefHandler::ID_NAV_BACK, L"Back",
browser_->UIT_CanGoBack(), label_list);
AddMenuItem(browser_, menu, -1, CefHandler::ID_NAV_FORWARD, L"Forward",
browser_->UIT_CanGoForward(), label_list);
AddMenuSeparator(menu, -1);
AddMenuItem(browser_, menu, -1, CefHandler::ID_PRINT, L"Print",
true, label_list);
AddMenuItem(browser_, menu, -1, CefHandler::ID_VIEWSOURCE, L"View Source",
true, label_list);
break;
}
if(menu) {
// show the context menu
int selected_id = TrackPopupMenu(menu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_RECURSE,
screen_pt.x, screen_pt.y, 0, browser_->UIT_GetMainWndHandle(), NULL);
if(selected_id != 0) {
// An action was chosen
CefHandler::MenuId menuId = static_cast<CefHandler::MenuId>(selected_id);
bool handled = false;
if(handler.get()) {
// Ask the handler if it wants to handle the action
CefHandler::RetVal rv = handler->HandleMenuAction(browser_, menuId);
handled = (rv == CefHandler::RV_HANDLED);
}
if(!handled) {
// Execute the action
browser_->UIT_HandleAction(menuId, CefBrowser::TF_FOCUSED);
}
}
}
DestroyMenu(menu);
end:
MessageLoop::current()->SetNestableTasksAllowed(old_state);
}
// Private methods -----------------------------------------------------------
void BrowserWebViewDelegate::ShowJavaScriptAlert(WebView* webview,
const std::wstring& message)
{
// TODO(cef): Think about what we should be showing as the prompt caption
MessageBox(browser_->UIT_GetMainWndHandle(), message.c_str(),
browser_->UIT_GetTitle().c_str(), MB_OK | MB_ICONWARNING);
}
bool BrowserWebViewDelegate::ShowJavaScriptConfirm(WebView* webview,
const std::wstring& message)
{
// TODO(cef): Think about what we should be showing as the prompt caption
int rv = MessageBox(browser_->UIT_GetMainWndHandle(), message.c_str(),
browser_->UIT_GetTitle().c_str(),
MB_YESNO | MB_ICONQUESTION);
return (rv == IDYES);
}
bool BrowserWebViewDelegate::ShowJavaScriptPrompt(WebView* webview,
const std::wstring& message,
const std::wstring& default_value,
std::wstring* result)
{
// TODO(cef): Implement a default prompt dialog
return false;
}

393
libcef/context.cc Normal file
View File

@ -0,0 +1,393 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "context.h"
#include "browser_impl.h"
#include "browser_resource_loader_bridge.h"
#include "browser_request_context.h"
#include "base/at_exit.h"
#include "base/icu_util.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/resource_util.h"
#include "base/stats_table.h"
#include "base/string_util.h"
#include "net/base/net_module.h"
#include <commctrl.h>
// Global CefContext pointer
CefRefPtr<CefContext> _Context;
static const char* kStatsFilePrefix = "libcef_";
static int kStatsFileThreads = 20;
static int kStatsFileCounters = 200;
bool CefInitialize()
{
// Return true if the context is already initialized
if(_Context.get())
return true;
// Create the new global context object
_Context = new CefContext();
// Initialize the glboal context
return _Context->Initialize();
}
void CefShutdown()
{
// Verify that the context is already initialized
if(!_Context.get())
return;
// Shut down the global context
_Context->Shutdown();
// Delete the global context object
_Context = NULL;
}
StringPiece GetRawDataResource(HMODULE module, int resource_id) {
void* data_ptr;
size_t data_size;
return base::GetDataResourceFromModule(module, resource_id, &data_ptr,
&data_size) ?
StringPiece(static_cast<char*>(data_ptr), data_size) : StringPiece();
}
// This is called indirectly by the network layer to access resources.
StringPiece NetResourceProvider(int key) {
return GetRawDataResource(::GetModuleHandle(NULL), key);
}
DWORD WINAPI ThreadHandlerUI(LPVOID lpParam)
{
CefContext *pContext = static_cast<CefContext*>(lpParam);
HRESULT res;
// Initialize common controls
res = CoInitialize(NULL);
DCHECK(SUCCEEDED(res));
INITCOMMONCONTROLSEX InitCtrlEx;
InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrlEx.dwICC = ICC_STANDARD_CLASSES;
InitCommonControlsEx(&InitCtrlEx);
// Start COM stuff
res = OleInitialize(NULL);
DCHECK(SUCCEEDED(res));
// Instantiate the AtExitManager to avoid asserts and possible memory leaks.
base::AtExitManager at_exit_manager;
// Instantiate the message loop for this thread.
MessageLoopForUI main_message_loop;
pContext->SetMessageLoopForUI(&main_message_loop);
// Initializing with a default context, which means no on-disk cookie DB,
// and no support for directory listings.
// TODO(cef): Either disable caching or send the cache files to a reasonable
// temporary directory
std::wstring cache_path;
PathService::Get(base::DIR_EXE, &cache_path);
BrowserResourceLoaderBridge::Init(
new BrowserRequestContext(cache_path, net::HttpCache::NORMAL));
// Load ICU data tables.
bool ret = icu_util::Initialize();
if(!ret) {
MessageBox(NULL, L"Failed to load the required icudt38 library",
L"CEF Initialization Error", MB_ICONERROR | MB_OK);
return 1;
}
// Config the network module so it has access to a limited set of resources.
net::NetModule::SetResourceProvider(NetResourceProvider);
// Load and initialize the stats table. Attempt to construct a somewhat
// unique name to isolate separate instances from each other.
StatsTable *table = new StatsTable(
kStatsFilePrefix + Uint64ToString(base::RandUint64()),
kStatsFileThreads,
kStatsFileCounters);
StatsTable::set_current(table);
// Notify the context that initialization is complete so that the
// Initialize() function can return.
pContext->NotifyEvent();
// Execute the message loop that will run until a quit task is received.
MessageLoop::current()->Run();
// Flush any remaining messages. This ensures that any accumulated
// Task objects get destroyed before we exit, which avoids noise in
// purify leak-test results.
MessageLoop::current()->RunAllPending();
BrowserResourceLoaderBridge::Shutdown();
// Tear down shared StatsTable; prevents unit_tests from leaking it.
StatsTable::set_current(NULL);
delete table;
// Uninitialize COM stuff
OleUninitialize();
// Uninitialize common controls
CoUninitialize();
return 0;
}
CefContext::CefContext()
{
hthreadui_ = NULL;
idthreadui_ = 0;
heventui_ = NULL;
messageloopui_ = NULL;
in_transition_ = false;
webprefs_ = NULL;
hinstance_ = ::GetModuleHandle(NULL);
}
CefContext::~CefContext()
{
// Just in case CefShutdown() isn't called
Shutdown();
}
bool CefContext::Initialize()
{
bool initialized = false, intransition = false;
Lock();
// We only need to initialize if the UI thread is not currently running
if(!hthreadui_) {
// Only start the initialization if we're not currently in a transitional
// state
intransition = in_transition_;
if(!intransition) {
// We are now in a transitional state
in_transition_ = true;
// Register the window class
WNDCLASSEX wcex = {
/* cbSize = */ sizeof(WNDCLASSEX),
/* style = */ CS_HREDRAW | CS_VREDRAW,
/* lpfnWndProc = */ CefBrowserImpl::WndProc,
/* cbClsExtra = */ 0,
/* cbWndExtra = */ 0,
/* hInstance = */ hinstance_,
/* hIcon = */ NULL,
/* hCursor = */ LoadCursor(NULL, IDC_ARROW),
/* hbrBackground = */ 0,
/* lpszMenuName = */ NULL,
/* lpszClassName = */ CefBrowserImpl::GetWndClass(),
/* hIconSm = */ NULL,
};
RegisterClassEx(&wcex);
// Initialize web preferences
webprefs_ = new WebPreferences;
*webprefs_ = WebPreferences();
webprefs_->standard_font_family = L"Times";
webprefs_->fixed_font_family = L"Courier";
webprefs_->serif_font_family = L"Times";
webprefs_->sans_serif_font_family = L"Helvetica";
// These two fonts are picked from the intersection of
// Win XP font list and Vista font list :
// http://www.microsoft.com/typography/fonts/winxp.htm
// http://blogs.msdn.com/michkap/archive/2006/04/04/567881.aspx
// Some of them are installed only with CJK and complex script
// support enabled on Windows XP and are out of consideration here.
// (although we enabled both on our buildbots.)
// They (especially Impact for fantasy) are not typical cursive
// and fantasy fonts, but it should not matter for layout tests
// as long as they're available.
#if defined(OS_MACOSX)
webprefs_->cursive_font_family = L"Apple Chancery";
webprefs_->fantasy_font_family = L"Papyrus";
#else
webprefs_->cursive_font_family = L"Comic Sans MS";
webprefs_->fantasy_font_family = L"Impact";
#endif
webprefs_->default_encoding = L"ISO-8859-1";
webprefs_->default_font_size = 16;
webprefs_->default_fixed_font_size = 13;
webprefs_->minimum_font_size = 1;
webprefs_->minimum_logical_font_size = 9;
webprefs_->javascript_can_open_windows_automatically = true;
webprefs_->dom_paste_enabled = true;
webprefs_->developer_extras_enabled = true;
webprefs_->shrinks_standalone_images_to_fit = false;
webprefs_->uses_universal_detector = false;
webprefs_->text_areas_are_resizable = false;
webprefs_->java_enabled = true;
webprefs_->allow_scripts_to_close_windows = false;
// Event that will be used to signal thread setup completion. Start
// in non-signaled mode so that the event will block.
heventui_ = CreateEvent(NULL, TRUE, FALSE, NULL);
DCHECK(heventui_ != NULL);
// Thread that hosts the UI loop
hthreadui_ = CreateThread(
NULL, 0, ThreadHandlerUI, this, 0, &idthreadui_);
DCHECK(hthreadui_ != NULL);
initialized = true;
}
}
Unlock();
if(initialized) {
// Wait for initial UI thread setup to complete
WaitForSingleObject(heventui_, INFINITE);
Lock();
// We have exited the transitional state
in_transition_ = false;
Unlock();
}
return intransition ? false : true;
}
void CefContext::Shutdown()
{
bool shutdown = false, intransition = false;
Lock();
// We only need to shut down if the UI thread is currently running
if(hthreadui_) {
// Only start the shutdown if we're not currently in a transitional state
intransition = in_transition_;
if(!intransition) {
DCHECK(messageloopui_ != NULL);
// We are now in a transitional state
in_transition_ = true;
if(browserlist_.size() > 0)
browserlist_.clear();
if(webprefs_) {
delete webprefs_;
webprefs_ = NULL;
}
// Post the quit message to the UI message loop
messageloopui_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
shutdown = true;
}
}
Unlock();
if(shutdown) {
// Wait for the UI thread to exit
WaitForSingleObject(hthreadui_, INFINITE);
Lock();
// Unregister the window class
UnregisterClass(CefBrowserImpl::GetWndClass(), hinstance_);
// Clean up thread and event handles
CloseHandle(hthreadui_);
CloseHandle(heventui_);
hthreadui_ = NULL;
idthreadui_ = 0;
heventui_ = NULL;
messageloopui_ = NULL;
// We have exited the transitional state
in_transition_ = false;
Unlock();
}
}
bool CefContext::AddBrowser(CefRefPtr<CefBrowserImpl> browser)
{
bool found = false;
Lock();
// check that the browser isn't already in the list before adding
BrowserList::const_iterator it = browserlist_.begin();
for(; it != browserlist_.end(); ++it) {
if(it->get() == browser.get()) {
found = true;
break;
}
}
if(!found)
browserlist_.push_back(browser);
Unlock();
return !found;
}
bool CefContext::RemoveBrowser(CefRefPtr<CefBrowserImpl> browser)
{
bool deleted = false;
Lock();
BrowserList::iterator it = browserlist_.begin();
for(; it != browserlist_.end(); ++it) {
if(it->get() == browser.get()) {
browserlist_.erase(it);
deleted = true;
break;
}
}
Unlock();
return deleted;
}
void CefContext::SetMessageLoopForUI(MessageLoopForUI* loop)
{
Lock();
messageloopui_ = loop;
Unlock();
}
void CefContext::NotifyEvent()
{
Lock();
// Set the event state to signaled so that the waiting thread will be
// released.
if(heventui_)
SetEvent(heventui_);
Unlock();
}
void PostTask(const tracked_objects::Location& from_here, Task* task)
{
if(_Context.get()) {
_Context->Lock();
MessageLoopForUI *pMsgLoop = _Context->GetMessageLoopForUI();
if(pMsgLoop)
pMsgLoop->PostTask(from_here, task);
_Context->Unlock();
}
}

67
libcef/context.h Normal file
View File

@ -0,0 +1,67 @@
// Copyright (c) 2008 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.
#ifndef _CONTEXT_H
#define _CONTEXT_H
#include "../include/cef.h"
#include "base/message_loop.h"
#include "base/gfx/native_widget_types.h"
#include "webkit/glue/webpreferences.h"
class CefBrowserImpl;
class CefContext : public CefThreadSafeBase<CefBase>
{
public:
typedef std::list<CefRefPtr<CefBrowserImpl> > BrowserList;
CefContext();
~CefContext();
bool Initialize();
void Shutdown();
MessageLoopForUI* GetMessageLoopForUI() { return messageloopui_; }
HMODULE GetInstanceHandle() { return hinstance_; }
HANDLE GetUIThreadHandle() { return hthreadui_; }
DWORD GetUIThreadId() { return idthreadui_; }
WebPreferences* GetWebPreferences() { return webprefs_; }
bool AddBrowser(CefRefPtr<CefBrowserImpl> browser);
bool RemoveBrowser(CefRefPtr<CefBrowserImpl> browser);
BrowserList* GetBrowserList() { return &browserlist_; }
// Returns true if the calling thread is the same as the UI thread
bool RunningOnUIThread() { return (GetCurrentThreadId() == idthreadui_); }
private:
void SetMessageLoopForUI(MessageLoopForUI* loop);
void NotifyEvent();
protected:
HMODULE hinstance_;
DWORD idthreadui_;
HANDLE hthreadui_;
HANDLE heventui_;
MessageLoopForUI* messageloopui_;
bool in_transition_;
BrowserList browserlist_;
WebPreferences* webprefs_;
friend DWORD WINAPI ThreadHandlerUI(LPVOID lpParam);
};
// Post a task to the UI message loop
void PostTask(const tracked_objects::Location& from_here, Task* task);
// Global context object pointer
extern CefRefPtr<CefContext> _Context;
// Macro for requiring that a function be called on the UI thread
#define REQUIRE_UIT() DCHECK(_Context->RunningOnUIThread())
#endif // _CONTEXT_H

278
libcef/jscontainer.cc Normal file
View File

@ -0,0 +1,278 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "jscontainer.h"
#include "variant_impl.h"
// Here's the control flow of a JS method getting forwarded to a class.
// - Something calls our NPObject with a function like "Invoke".
// - CefNPObject's static invoke() function forwards it to its attached
// CefJSContainer's Invoke() method.
// - CefJSContainer has then overridden Invoke() to look up the function
// name in its internal map of methods, and then calls the appropriate
// method.
#include "base/compiler_specific.h"
#include "config.h"
// This is required for the KJS build due to an artifact of the
// npruntime_priv.h file from JavaScriptCore/bindings.
MSVC_PUSH_DISABLE_WARNING(4067)
#include "npruntime_priv.h"
MSVC_POP_WARNING()
#if USE(JSC)
MSVC_PUSH_WARNING_LEVEL(0)
#include <runtime/JSLock.h>
MSVC_POP_WARNING()
#endif
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "webkit/glue/webframe.h"
// Our special NPObject type. We extend an NPObject with a pointer to a
// CefJSContainer, which is just a C++ interface that we forward all NPObject
// callbacks to.
struct CefNPObject {
NPObject parent; // This must be the first field in the struct.
CefRefPtr<CefJSContainer> container;
WebFrame* webframe;
//
// All following objects and functions are static, and just used to interface
// with NPObject/NPClass.
//
// An NPClass associates static functions of CefNPObject with the
// function pointers used by the JS runtime.
static NPClass np_class_;
// Allocate a new NPObject with the specified class.
static NPObject* allocate(NPP npp, NPClass* aClass);
// Free an object.
static void deallocate(NPObject* obj);
// Returns true if the C++ class associated with this NPObject exposes the
// given property. Called by the JS runtime.
static bool hasProperty(NPObject *obj, NPIdentifier ident);
// Returns true if the C++ class associated with this NPObject exposes the
// given method. Called by the JS runtime.
static bool hasMethod(NPObject *obj, NPIdentifier ident);
// If the given method is exposed by the C++ class associated with this
// NPObject, invokes it with the given args and returns a result. Otherwise,
// returns "undefined" (in the JavaScript sense). Called by the JS runtime.
static bool invoke(NPObject *obj, NPIdentifier ident,
const NPVariant *args, uint32_t arg_count,
NPVariant *result);
// If the given property is exposed by the C++ class associated with this
// NPObject, returns its value. Otherwise, returns "undefined" (in the
// JavaScript sense). Called by the JS runtime.
static bool getProperty(NPObject *obj, NPIdentifier ident,
NPVariant *result);
// If the given property is exposed by the C++ class associated with this
// NPObject, sets its value. Otherwise, does nothing. Called by the JS
// runtime.
static bool setProperty(NPObject *obj, NPIdentifier ident,
const NPVariant *value);
};
// Build CefNPObject's static function pointers into an NPClass, for use
// in constructing NPObjects for the C++ classes.
NPClass CefNPObject::np_class_ = {
NP_CLASS_STRUCT_VERSION,
CefNPObject::allocate,
CefNPObject::deallocate,
/* NPInvalidateFunctionPtr */ NULL,
CefNPObject::hasMethod,
CefNPObject::invoke,
/* NPInvokeDefaultFunctionPtr */ NULL,
CefNPObject::hasProperty,
CefNPObject::getProperty,
CefNPObject::setProperty,
/* NPRemovePropertyFunctionPtr */ NULL
};
/* static */ NPObject* CefNPObject::allocate(NPP npp, NPClass* aClass) {
CefNPObject* obj = new CefNPObject;
// obj->parent will be initialized by the NPObject code calling this.
obj->container = NULL;
return &obj->parent;
}
/* static */ void CefNPObject::deallocate(NPObject* np_obj) {
CefNPObject* obj = reinterpret_cast<CefNPObject*>(np_obj);
delete obj;
}
/* static */ bool CefNPObject::hasMethod(NPObject* np_obj,
NPIdentifier ident) {
CefNPObject* obj = reinterpret_cast<CefNPObject*>(np_obj);
return obj->container->HasMethod(ident);
}
/* static */ bool CefNPObject::hasProperty(NPObject* np_obj,
NPIdentifier ident) {
CefNPObject* obj = reinterpret_cast<CefNPObject*>(np_obj);
return obj->container->HasProperty(ident);
}
/* static */ bool CefNPObject::invoke(NPObject* np_obj, NPIdentifier ident,
const NPVariant* args, uint32_t arg_count,
NPVariant* result) {
CefNPObject* obj = reinterpret_cast<CefNPObject*>(np_obj);
return obj->container->Invoke(ident, obj->webframe, args, arg_count, result);
}
/* static */ bool CefNPObject::getProperty(NPObject* np_obj,
NPIdentifier ident,
NPVariant* result) {
CefNPObject* obj = reinterpret_cast<CefNPObject*>(np_obj);
return obj->container->GetProperty(ident, obj->webframe, result);
}
/* static */ bool CefNPObject::setProperty(NPObject* np_obj,
NPIdentifier ident,
const NPVariant* value) {
CefNPObject* obj = reinterpret_cast<CefNPObject*>(np_obj);
return obj->container->SetProperty(ident, obj->webframe, value);
}
CefJSContainer::CefJSContainer(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefJSHandler> handler)
: browser_(browser), handler_(handler)
{
DCHECK(browser_.get() != NULL);
DCHECK(handler_.get() != NULL);
}
CefJSContainer::~CefJSContainer()
{
// Unregister objects we created and bound to a frame.
for (BoundObjectList::iterator i = bound_objects_.begin();
i != bound_objects_.end(); ++i) {
#if USE(V8)
_NPN_UnregisterObject(*i);
#endif
NPN_ReleaseObject(*i);
}
}
bool CefJSContainer::HasMethod(NPIdentifier ident)
{
std::wstring name = UTF8ToWide(NPN_UTF8FromIdentifier(ident));
return handler_->HasMethod(browser_, name);
}
bool CefJSContainer::HasProperty(NPIdentifier ident)
{
std::wstring name = UTF8ToWide(NPN_UTF8FromIdentifier(ident));
return handler_->HasProperty(browser_, name);
}
bool CefJSContainer::Invoke(NPIdentifier ident,
WebFrame* frame,
const NPVariant* args,
size_t arg_count,
NPVariant* result)
{
std::wstring name = UTF8ToWide(NPN_UTF8FromIdentifier(ident));
// Build a VariantVector argument vector from the NPVariants coming in.
CefJSHandler::VariantVector cef_args(arg_count);
for (size_t i = 0; i < arg_count; i++) {
cef_args[i] = new CefVariantImpl(frame);
static_cast<CefVariantImpl*>(cef_args[i].get())->Set(args[i]);
}
CefRefPtr<CefVariant> cef_retval(new CefVariantImpl(frame));
// Execute the handler method
bool rv = handler_->ExecuteMethod(browser_, name, cef_args, cef_retval);
if(rv) {
// Assign the return value
static_cast<CefVariantImpl*>(cef_retval.get())->CopyToNPVariant(result);
}
return rv;
}
bool CefJSContainer::GetProperty(NPIdentifier ident,
WebFrame* frame,
NPVariant* result)
{
CefRefPtr<CefVariant> cef_result(new CefVariantImpl(frame));
std::wstring name = UTF8ToWide(NPN_UTF8FromIdentifier(ident));
// Execute the handler method
bool rv = handler_->GetProperty(browser_, name, cef_result);
if(rv) {
// Assign the return value
static_cast<CefVariantImpl*>(cef_result.get())->CopyToNPVariant(result);
}
return rv;
}
bool CefJSContainer::SetProperty(NPIdentifier ident,
WebFrame* frame,
const NPVariant* value)
{
std::wstring name = UTF8ToWide(NPN_UTF8FromIdentifier(ident));
// Assign the input value
CefRefPtr<CefVariant> cef_value(new CefVariantImpl(frame));
static_cast<CefVariantImpl*>(cef_value.get())->Set(*value);
// Execute the handler method
return handler_->SetProperty(browser_, name, cef_value);
}
void CefJSContainer::BindToJavascript(WebFrame* frame,
const std::wstring& classname) {
#if USE(JSC)
JSC::JSLock lock(false);
#endif
NPObject* np_obj = NULL;
CefNPObject* obj = NULL;
// Check if we already have an NPObject bound to this particular frame.
Lock();
BoundObjectList::const_iterator it = bound_objects_.begin();
for(; it != bound_objects_.end(); ++it) {
obj = reinterpret_cast<CefNPObject*>(*it);
if(obj->webframe == frame) {
np_obj = *it;
break;
}
}
Unlock();
if(!np_obj) {
// Create an NPObject using our static NPClass. The first argument (a
// plugin's instance handle) is passed through to the allocate function
// directly, and we don't use it, so it's ok to be 0.
np_obj = NPN_CreateObject(0, &CefNPObject::np_class_);
obj = reinterpret_cast<CefNPObject*>(np_obj);
obj->container = this;
obj->webframe = frame;
Lock();
bound_objects_.push_back(np_obj);
Unlock();
}
// BindToWindowObject will (indirectly) retain the np_object. We save it
// so we can release it when we're destroyed.
frame->BindToWindowObject(classname, np_obj);
}

65
libcef/jscontainer.h Normal file
View File

@ -0,0 +1,65 @@
// Copyright (c) 2008 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.
#ifndef _JSCONTAINER_H
#define _JSCONTAINER_H
#include "../include/cef.h"
#include "third_party/npapi/bindings/npruntime.h"
class WebFrame;
// CefJSContainer lets you map Javascript method calls and property accesses
// directly to C++ method calls and CefVariant* variable access.
// Portions of the implementation are borrowed from
// webkit\glue\cpp_bound_class.cc
class CefJSContainer : public CefThreadSafeBase<CefBase>
{
public:
CefJSContainer(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefJSHandler> handler);
~CefJSContainer();
// Given a WebFrame, BindToJavascript builds the NPObject that will represent
// the class and binds it to the frame's window under the given name. This
// should generally be called from the WebView delegate's
// WindowObjectCleared(). A class so bound will be accessible to JavaScript
// as window.<classname>. The owner of the CefJSContainer is responsible for
// keeping the object around while the frame is alive, and for destroying it
// afterwards.
void BindToJavascript(WebFrame* frame,
const std::wstring& classname);
CefRefPtr<CefJSHandler> GetHandler() { return handler_; }
protected:
bool HasMethod(NPIdentifier ident);
bool HasProperty(NPIdentifier ident);
bool Invoke(NPIdentifier ident,
WebFrame* frame,
const NPVariant* args,
size_t arg_count,
NPVariant* result);
bool GetProperty(NPIdentifier ident,
WebFrame* frame,
NPVariant* result);
bool SetProperty(NPIdentifier ident,
WebFrame* frame,
const NPVariant* value);
friend struct CefNPObject;
protected:
CefRefPtr<CefBrowser> browser_;
CefRefPtr<CefJSHandler> handler_;
// A list of all NPObjects we created and bound in BindToJavascript(), so we
// can clean them up when we're destroyed.
typedef std::vector<NPObject*> BoundObjectList;
BoundObjectList bound_objects_;
};
#endif // _JSHANDLER_CONTAINER_H

363
libcef/libcef.vcproj Normal file
View File

@ -0,0 +1,363 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="libcef"
ProjectGUID="{FA39524D-3067-4141-888D-28A86C66F2B9}"
RootNamespace="libcef"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
ConfigurationType="4"
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\libcef.vsprops"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="precompiled_libcef.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
ConfigurationType="4"
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\libcef.vsprops"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="precompiled_libcef.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="printing"
>
<File
RelativePath=".\printing\page_number.cc"
>
</File>
<File
RelativePath=".\printing\page_number.h"
>
</File>
<File
RelativePath=".\printing\page_range.cc"
>
</File>
<File
RelativePath=".\printing\page_range.h"
>
</File>
<File
RelativePath=".\printing\page_setup.cc"
>
</File>
<File
RelativePath=".\printing\page_setup.h"
>
</File>
<File
RelativePath=".\printing\print_settings.cc"
>
</File>
<File
RelativePath=".\printing\print_settings.h"
>
</File>
<File
RelativePath=".\printing\units.cc"
>
</File>
<File
RelativePath=".\printing\units.h"
>
</File>
<File
RelativePath=".\printing\win_printing_context.cc"
>
</File>
<File
RelativePath=".\printing\win_printing_context.h"
>
</File>
</Filter>
<Filter
Name="include"
>
<File
RelativePath="..\include\cef.h"
>
</File>
<File
RelativePath="..\include\cef_ptr.h"
>
</File>
<File
RelativePath="..\include\cef_win.h"
>
</File>
</Filter>
<File
RelativePath=".\browser_drag_delegate.cc"
>
</File>
<File
RelativePath=".\browser_drag_delegate.h"
>
</File>
<File
RelativePath=".\browser_drop_delegate.cc"
>
</File>
<File
RelativePath=".\browser_drop_delegate.h"
>
</File>
<File
RelativePath=".\browser_impl.cc"
>
</File>
<File
RelativePath=".\browser_impl.h"
>
</File>
<File
RelativePath=".\browser_impl_win.cc"
>
</File>
<File
RelativePath=".\browser_navigation_controller.cc"
>
</File>
<File
RelativePath=".\browser_navigation_controller.h"
>
</File>
<File
RelativePath=".\browser_request_context.cc"
>
</File>
<File
RelativePath=".\browser_request_context.h"
>
</File>
<File
RelativePath=".\browser_resource_loader_bridge.cc"
>
</File>
<File
RelativePath=".\browser_resource_loader_bridge.h"
>
</File>
<File
RelativePath=".\browser_webkit_glue.cc"
>
</File>
<File
RelativePath=".\browser_webkit_glue.h"
>
</File>
<File
RelativePath=".\browser_webkit_glue_win.cc"
>
</File>
<File
RelativePath=".\browser_webview_delegate.cc"
>
</File>
<File
RelativePath=".\browser_webview_delegate.h"
>
</File>
<File
RelativePath=".\browser_webview_delegate_win.cc"
>
</File>
<File
RelativePath=".\context.cc"
>
</File>
<File
RelativePath=".\context.h"
>
</File>
<File
RelativePath=".\jscontainer.cc"
>
</File>
<File
RelativePath=".\jscontainer.h"
>
</File>
<File
RelativePath=".\precompiled_libcef.cc"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\precompiled_libcef.h"
>
</File>
<File
RelativePath=".\request_impl.cc"
>
</File>
<File
RelativePath=".\request_impl.h"
>
</File>
<File
RelativePath=".\stream_impl.cc"
>
</File>
<File
RelativePath=".\stream_impl.h"
>
</File>
<File
RelativePath=".\variant_impl.cc"
>
</File>
<File
RelativePath=".\variant_impl.h"
>
</File>
<File
RelativePath=".\variant_np_util.cc"
>
</File>
<File
RelativePath=".\variant_np_util.h"
>
</File>
<File
RelativePath=".\webview_host.cc"
>
</File>
<File
RelativePath=".\webview_host.h"
>
</File>
<File
RelativePath=".\webwidget_host.cc"
>
</File>
<File
RelativePath=".\webwidget_host.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

22
libcef/libcef.vsprops Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="libcef"
InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\third_party\libpng\using_libpng.vsprops;$(SolutionDir)..\breakpad\using_breakpad.vsprops;$(SolutionDir)..\third_party\libxml\build\using_libxml.vsprops;$(SolutionDir)..\third_party\npapi\using_npapi.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;.\libcef_webkit.vsprops"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(OutDir)\WebKit&quot;;&quot;$(SolutionDir)&quot;;&quot;$(IntDir)\..\localized_strings&quot;;&quot;$(SolutionDir)..\webkit\port\bridge&quot;;&quot;$(SolutionDir)..\webkit\port\platform&quot;;&quot;$(SolutionDir)..\webkit\port\platform\network&quot;;&quot;$(SolutionDir)..\webkit\glue&quot;;&quot;$(SolutionDir)..\third_party\webkit\src\&quot;;&quot;$(OutDir)\obj\WebCore\JavaScriptHeaders&quot;;&quot;$(OutDir)&quot;"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib shlwapi.lib rpcrt4.lib winmm.lib"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(IntDir)\..\&quot;"
/>
</VisualStudioPropertySheet>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="webkit_common"
InheritedPropertySheets=".\libcef_webkit_includes.vsprops;$(SolutionDir)..\webkit\build\webkit_common_defines.vsprops;$(SolutionDir)..\webkit\build\js_engine$(JS_ENGINE_TYPE).vsprops;$(SolutionDir)..\third_party\npapi\using_npapi.vsprops;$(SolutionDir)..\skia\using_skia.vsprops;$(SolutionDir)..\build\external_code.vsprops;$(SolutionDir)..\third_party\icu38\build\using_icu.vsprops"
>
</VisualStudioPropertySheet>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="webkit_common_includes"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(OutDir)\obj\WebCore&quot;;&quot;$(OutDir)\obj\WebCore\JavaScriptHeaders&quot;;&quot;$(OutDir)\obj\WebCore\JavaScriptHeaders\JavaScriptCore&quot;;&quot;$(SolutionDir)..\webkit\pending\&quot;;&quot;$(SolutionDir)..\webkit\pending\kjs&quot;;&quot;$(SolutionDir)..\webkit\pending\wtf&quot;;&quot;$(SolutionDir)..\webkit\port\bridge&quot;;&quot;$(SolutionDir)..\webkit\port\css&quot;;&quot;$(SolutionDir)..\webkit\port\dom&quot;;&quot;$(SolutionDir)..\webkit\port\history&quot;;&quot;$(SolutionDir)..\webkit\port\loader&quot;;&quot;$(SolutionDir)..\webkit\port\page&quot;;&quot;$(SolutionDir)..\webkit\port\page\chromium&quot;;&quot;$(SolutionDir)..\webkit\port\page\win&quot;;&quot;$(SolutionDir)..\webkit\port\platform&quot;;&quot;$(SolutionDir)..\webkit\port\platform\chromium&quot;;&quot;$(SolutionDir)..\webkit\port\platform\win&quot;;&quot;$(SolutionDir)..\webkit\port\platform\network\chromium&quot;;&quot;$(SolutionDir)..\webkit\port\platform\image-decoders&quot;;&quot;$(SolutionDir)..\webkit\port\platform\image-decoders\bmp&quot;;&quot;$(SolutionDir)..\webkit\port\platform\image-decoders\gif&quot;;&quot;$(SolutionDir)..\webkit\port\platform\image-decoders\ico&quot;;&quot;$(SolutionDir)..\webkit\port\platform\image-decoders\jpeg&quot;;&quot;$(SolutionDir)..\webkit\port\platform\image-decoders\png&quot;;&quot;$(SolutionDir)..\webkit\port\platform\image-decoders\xbm&quot;;&quot;$(SolutionDir)..\webkit\port\platform\network&quot;;&quot;$(SolutionDir)..\webkit\port\plugins&quot;;&quot;$(SolutionDir)..\webkit\port\rendering&quot;;&quot;$(SolutionDir)..\webkit\port\platform\graphics&quot;;&quot;$(SolutionDir)..\webkit\port\platform\graphics\chromium&quot;;&quot;$(SolutionDir)..\webkit&quot;;&quot;$(SolutionDir)..\webkit\build&quot;;&quot;$(ProjectDir)&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\bridge&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\bridge\c&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\css&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\dom&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\editing&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\history&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\html&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\loader&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\loader\appcache&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\loader\archive&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\loader\icon&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\page&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\platform&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\page\animation&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\platform\text&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\platform\graphics&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\svg\graphics&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\platform\network&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\platform\sql&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\rendering&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\rendering\style&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\storage&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\xml&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\os-win32&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\wtf&quot;;&quot;$(SolutionDir)..\third_party\WebKit\JavaScriptCore&quot;;&quot;$(SolutionDir)..\third_party\WebKit\JavaScriptCore\wtf&quot;;&quot;$(SolutionDir)..\third_party\WebKit\JavaScriptCore\os-win32&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\svg&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\svg\animation&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\svg\graphics\filters&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\plugins&quot;;&quot;$(SolutionDir)..\third_party\WebKit\WebCore\inspector&quot;;&quot;$(SolutionDir)..\third_party\sqlite&quot;;&quot;$(SDKIncludes)&quot;;&quot;$(IntDir)\..\WebCore\DerivedSources&quot;;"
/>
</VisualStudioPropertySheet>

View File

@ -0,0 +1,5 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"

View File

@ -0,0 +1,7 @@
// Copyright (c) 2008 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 <string>
#include <map>
#include <vector>

View File

@ -0,0 +1,85 @@
// 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 "precompiled_libcef.h"
#include "page_number.h"
#include "print_settings.h"
#include <limits>
#include "base/logging.h"
namespace printing {
PageNumber::PageNumber(const PrintSettings& settings, int document_page_count) {
Init(settings, document_page_count);
}
PageNumber::PageNumber()
: ranges_(NULL),
page_number_(-1),
page_range_index_(-1),
document_page_count_(0) {
}
void PageNumber::operator=(const PageNumber& other) {
ranges_ = other.ranges_;
page_number_ = other.page_number_;
page_range_index_ = other.page_range_index_;
document_page_count_ = other.document_page_count_;
}
void PageNumber::Init(const PrintSettings& settings, int document_page_count) {
DCHECK(document_page_count);
ranges_ = settings.ranges.empty() ? NULL : &settings.ranges;
document_page_count_ = document_page_count;
if (ranges_) {
page_range_index_ = 0;
page_number_ = (*ranges_)[0].from;
} else {
if (document_page_count) {
page_number_ = 0;
} else {
page_number_ = -1;
}
page_range_index_ = -1;
}
}
int PageNumber::operator++() {
if (!ranges_) {
// Switch to next page.
if (++page_number_ == document_page_count_) {
// Finished.
*this = npos();
}
} else {
// Switch to next page.
++page_number_;
// Page ranges are inclusive.
if (page_number_ > (*ranges_)[page_range_index_].to) {
DCHECK(ranges_->size() <= static_cast<size_t>(
std::numeric_limits<int>::max()));
if (++page_range_index_ == static_cast<int>(ranges_->size())) {
// Finished.
*this = npos();
} else {
page_number_ = (*ranges_)[page_range_index_].from;
}
}
}
return ToInt();
}
bool PageNumber::operator==(const PageNumber& other) const {
return page_number_ == other.page_number_ &&
page_range_index_ == other.page_range_index_;
}
bool PageNumber::operator!=(const PageNumber& other) const {
return page_number_ != other.page_number_ ||
page_range_index_ != other.page_range_index_;
}
} // namespace printing

View File

@ -0,0 +1,74 @@
// 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.
#ifndef _PRINTING_PAGE_NUMBER_H
#define _PRINTING_PAGE_NUMBER_H
#include <ostream>
#include "page_range.h"
namespace printing {
class PrintSettings;
// Represents a page series following the array of page ranges defined in a
// PrintSettings.
class PageNumber {
public:
// Initializes the page to the first page in the settings's range or 0.
PageNumber(const PrintSettings& settings, int document_page_count);
PageNumber();
void operator=(const PageNumber& other);
// Initializes the page to the first page in the setting's range or 0. It
// initialize to npos if the range is empty and document_page_count is 0.
void Init(const PrintSettings& settings, int document_page_count);
// Converts to a page numbers.
int ToInt() const {
return page_number_;
}
// Calculates the next page in the serie.
int operator++();
// Returns an instance that represents the end of a serie.
static const PageNumber npos() {
return PageNumber();
}
// Equality operator. Only the current page number is verified so that
// "page != PageNumber::npos()" works.
bool operator==(const PageNumber& other) const;
bool operator!=(const PageNumber& other) const;
private:
// The page range to follow.
const PageRanges* ranges_;
// The next page to be printed. -1 when not printing.
int page_number_;
// The next page to be printed. -1 when not used. Valid only if
// document()->settings().range.empty() is false.
int page_range_index_;
// Number of expected pages in the document. Used when ranges_ is NULL.
int document_page_count_;
};
// Debug output support.
template<class E, class T>
inline typename std::basic_ostream<E,T>& operator<<(
typename std::basic_ostream<E,T>& ss, const PageNumber& page) {
return ss << page.ToInt();
}
} // namespace printing
#endif // _PRINTING_PAGE_NUMBER_H

View File

@ -0,0 +1,25 @@
// 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 "precompiled_libcef.h"
#include "page_range.h"
#include "chrome/common/stl_util-inl.h"
namespace printing {
std::vector<int> PageRange::GetPages(const PageRanges& ranges) {
std::set<int> pages;
for (unsigned i = 0; i < ranges.size(); ++i) {
const PageRange& range = ranges[i];
// Ranges are inclusive.
for (int i = range.from; i <= range.to; ++i) {
pages.insert(i);
}
}
return SetToVector(pages);
}
} // namespace printing

View File

@ -0,0 +1,32 @@
// 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.
#ifndef _PRINTING_PAGE_RANGE_H
#define _PRINTING_PAGE_RANGE_H
#include <vector>
namespace printing {
struct PageRange;
typedef std::vector<PageRange> PageRanges;
// Print range is inclusive. To select one page, set from == to.
struct PageRange {
int from;
int to;
bool operator==(const PageRange& rhs) const {
return from == rhs.from && to == rhs.to;
}
// Retrieves the sorted list of unique pages in the page ranges.
static std::vector<int> GetPages(const PageRanges& ranges);
};
} // namespace printing
#endif // _PRINTING_PAGE_RANGE_H

View File

@ -0,0 +1,128 @@
// 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 "precompiled_libcef.h"
#include "page_setup.h"
#include "base/logging.h"
namespace printing {
PageMargins::PageMargins()
: header(0),
footer(0),
left(0),
right(0),
top(0),
bottom(0) {
}
void PageMargins::Clear() {
header = 0;
footer = 0;
left = 0;
right = 0;
top = 0;
bottom = 0;
}
bool PageMargins::Equals(const PageMargins& rhs) const {
return header == rhs.header &&
footer == rhs.footer &&
left == rhs.left &&
top == rhs.top &&
right == rhs.right &&
bottom == rhs.bottom;
}
PageSetup::PageSetup() : text_height_(0) {
}
void PageSetup::Clear() {
physical_size_.SetSize(0, 0);
printable_area_.SetRect(0, 0, 0, 0);
overlay_area_.SetRect(0, 0, 0, 0);
content_area_.SetRect(0, 0, 0, 0);
effective_margins_.Clear();
text_height_ = 0;
}
bool PageSetup::Equals(const PageSetup& rhs) const {
return physical_size_ == rhs.physical_size_ &&
printable_area_ == rhs.printable_area_ &&
overlay_area_ == rhs.overlay_area_ &&
content_area_ == rhs.content_area_ &&
effective_margins_.Equals(rhs.effective_margins_) &&
requested_margins_.Equals(rhs.requested_margins_) &&
text_height_ == rhs.text_height_;
}
void PageSetup::Init(const gfx::Size& physical_size,
const gfx::Rect& printable_area,
int text_height) {
DCHECK_LE(printable_area.right(), physical_size.width());
// I've seen this assert triggers on Canon GP160PF PCL 5e and HP LaserJet 5.
// Since we don't know the dpi here, just disable the check.
// DCHECK_LE(printable_area.bottom(), physical_size.height());
DCHECK_GE(printable_area.x(), 0);
DCHECK_GE(printable_area.y(), 0);
DCHECK_GE(text_height, 0);
physical_size_ = physical_size;
printable_area_ = printable_area;
text_height_ = text_height;
// Calculate the effective margins. The tricky part.
effective_margins_.header = std::max(requested_margins_.header,
printable_area_.y());
effective_margins_.footer = std::max(requested_margins_.footer,
physical_size.height() -
printable_area_.bottom());
effective_margins_.left = std::max(requested_margins_.left,
printable_area_.x());
effective_margins_.top = std::max(std::max(requested_margins_.top,
printable_area_.y()),
effective_margins_.header + text_height);
effective_margins_.right = std::max(requested_margins_.right,
physical_size.width() -
printable_area_.right());
effective_margins_.bottom = std::max(std::max(requested_margins_.bottom,
physical_size.height() -
printable_area_.bottom()),
effective_margins_.footer + text_height);
// Calculate the overlay area. If the margins are excessive, the overlay_area
// size will be (0, 0).
overlay_area_.set_x(effective_margins_.left);
overlay_area_.set_y(effective_margins_.header);
overlay_area_.set_width(std::max(0,
physical_size.width() -
effective_margins_.right -
overlay_area_.x()));
overlay_area_.set_height(std::max(0,
physical_size.height() -
effective_margins_.footer -
overlay_area_.y()));
// Calculate the content area. If the margins are excessive, the content_area
// size will be (0, 0).
content_area_.set_x(effective_margins_.left);
content_area_.set_y(effective_margins_.top);
content_area_.set_width(std::max(0,
physical_size.width() -
effective_margins_.right -
content_area_.x()));
content_area_.set_height(std::max(0,
physical_size.height() -
effective_margins_.bottom -
content_area_.y()));
}
void PageSetup::SetRequestedMargins(const PageMargins& requested_margins) {
requested_margins_ = requested_margins;
if (physical_size_.width() && physical_size_.height())
Init(physical_size_, printable_area_, text_height_);
}
} // namespace printing

View File

@ -0,0 +1,83 @@
// 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.
#ifndef _PRINTING_PAGE_SETUP_H
#define _PRINTING_PAGE_SETUP_H
#include "base/gfx/rect.h"
namespace printing {
// Margins for a page setup.
class PageMargins {
public:
PageMargins();
void Clear();
// Equality operator.
bool Equals(const PageMargins& rhs) const;
// Vertical space for the overlay from the top of the sheet.
int header;
// Vertical space for the overlay from the bottom of the sheet.
int footer;
// Margin on each side of the sheet.
int left;
int right;
int top;
int bottom;
};
// Settings that define the size and printable areas of a page. Unit is
// unspecified.
class PageSetup {
public:
PageSetup();
void Clear();
// Equality operator.
bool Equals(const PageSetup& rhs) const;
void Init(const gfx::Size& physical_size, const gfx::Rect& printable_area,
int text_height);
void SetRequestedMargins(const PageMargins& requested_margins);
const gfx::Size& physical_size() const { return physical_size_; }
const gfx::Rect& overlay_area() const { return overlay_area_; }
const gfx::Rect& content_area() const { return content_area_; }
const PageMargins& effective_margins() const {
return effective_margins_;
}
private:
// Physical size of the page, including non-printable margins.
gfx::Size physical_size_;
// The printable area as specified by the printer driver. We can't get
// larger than this.
gfx::Rect printable_area_;
// The printable area for headers and footers.
gfx::Rect overlay_area_;
// The printable area as selected by the user's margins.
gfx::Rect content_area_;
// Effective margins.
PageMargins effective_margins_;
// Requested margins.
PageMargins requested_margins_;
// Space that must be kept free for the overlays.
int text_height_;
};
} // namespace printing
#endif // _PRINTING_PAGE_SETUP_H

View File

@ -0,0 +1,173 @@
// 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 "precompiled_libcef.h"
#include "print_settings.h"
#include "units.h"
#include "base/atomic_sequence_num.h"
#include "base/logging.h"
namespace printing {
// Global SequenceNumber used for generating unique cookie values.
static base::AtomicSequenceNumber cookie_seq(base::LINKER_INITIALIZED);
PrintSettings::PrintSettings()
: min_shrink(1.25),
max_shrink(2.0),
desired_dpi(72),
dpi_(0),
landscape_(false) {
}
void PrintSettings::Clear() {
ranges.clear();
min_shrink = 1.25;
max_shrink = 2.;
desired_dpi = 72;
printer_name_.clear();
device_name_.clear();
page_setup_cmm_.Clear();
page_setup_pixels_.Clear();
dpi_ = 0;
landscape_ = false;
}
#ifdef WIN32
void PrintSettings::Init(HDC hdc,
const DEVMODE& dev_mode,
const PageRanges& new_ranges,
const std::wstring& new_device_name) {
DCHECK(hdc);
printer_name_ = dev_mode.dmDeviceName;
device_name_ = new_device_name;
ranges = new_ranges;
landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;
int old_dpi = dpi_;
dpi_ = GetDeviceCaps(hdc, LOGPIXELSX);
// No printer device is known to advertise different dpi in X and Y axis; even
// the fax device using the 200x100 dpi setting. It's ought to break so many
// applications that it's not even needed to care about. WebKit doesn't
// support different dpi settings in X and Y axis.
DCHECK_EQ(dpi_, GetDeviceCaps(hdc, LOGPIXELSY));
DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORX), 0);
DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORY), 0);
// Initialize page_setup_pixels_.
gfx::Size physical_size_pixels(GetDeviceCaps(hdc, PHYSICALWIDTH),
GetDeviceCaps(hdc, PHYSICALHEIGHT));
gfx::Rect printable_area_pixels(GetDeviceCaps(hdc, PHYSICALOFFSETX),
GetDeviceCaps(hdc, PHYSICALOFFSETY),
GetDeviceCaps(hdc, HORZRES),
GetDeviceCaps(hdc, VERTRES));
// Hard-code text_height = 0.5cm = ~1/5 of inch
page_setup_pixels_.Init(physical_size_pixels, printable_area_pixels,
ConvertUnit(500, kHundrethsMMPerInch, dpi_));
// Initialize page_setup_cmm_.
// In theory, we should be using HORZSIZE and VERTSIZE but their value is
// so wrong it's useless. So read the values in dpi unit and convert them back
// in 0.01 mm.
gfx::Size physical_size_cmm(
ConvertUnit(physical_size_pixels.width(), dpi_, kHundrethsMMPerInch),
ConvertUnit(physical_size_pixels.height(), dpi_, kHundrethsMMPerInch));
gfx::Rect printable_area_cmm(
ConvertUnit(printable_area_pixels.x(), dpi_, kHundrethsMMPerInch),
ConvertUnit(printable_area_pixels.y(), dpi_, kHundrethsMMPerInch),
ConvertUnit(printable_area_pixels.width(), dpi_, kHundrethsMMPerInch),
ConvertUnit(printable_area_pixels.bottom(), dpi_, kHundrethsMMPerInch));
static const int kRoundingTolerance = 5;
// Some printers may advertise a slightly larger printable area than the
// physical area. This is mostly due to integer calculation and rounding.
if (physical_size_cmm.height() > printable_area_cmm.bottom() &&
physical_size_cmm.height() <= (printable_area_cmm.bottom() +
kRoundingTolerance)) {
physical_size_cmm.set_height(printable_area_cmm.bottom());
}
if (physical_size_cmm.width() > printable_area_cmm.right() &&
physical_size_cmm.width() <= (printable_area_cmm.right() +
kRoundingTolerance)) {
physical_size_cmm.set_width(printable_area_cmm.right());
}
page_setup_cmm_.Init(physical_size_cmm, printable_area_cmm, 500);
}
#endif
void PrintSettings::UpdateMarginsMetric(const PageMargins& new_margins) {
// Apply the new margins in 0.01 mm unit.
page_setup_cmm_.SetRequestedMargins(new_margins);
// Converts the margins in dpi unit and apply those too.
PageMargins pixels_margins;
pixels_margins.header = ConvertUnit(new_margins.header, kHundrethsMMPerInch,
dpi_);
pixels_margins.footer = ConvertUnit(new_margins.footer, kHundrethsMMPerInch,
dpi_);
pixels_margins.left = ConvertUnit(new_margins.left, kHundrethsMMPerInch,
dpi_);
pixels_margins.top = ConvertUnit(new_margins.top, kHundrethsMMPerInch, dpi_);
pixels_margins.right = ConvertUnit(new_margins.right, kHundrethsMMPerInch,
dpi_);
pixels_margins.bottom = ConvertUnit(new_margins.bottom, kHundrethsMMPerInch,
dpi_);
page_setup_pixels_.SetRequestedMargins(pixels_margins);
}
void PrintSettings::UpdateMarginsMilliInch(const PageMargins& new_margins) {
// Convert margins from thousandth inches to cmm (0.01mm).
PageMargins cmm_margins;
cmm_margins.header =
ConvertMilliInchToHundredThousanthMeter(new_margins.header);
cmm_margins.footer =
ConvertMilliInchToHundredThousanthMeter(new_margins.footer);
cmm_margins.left = ConvertMilliInchToHundredThousanthMeter(new_margins.left);
cmm_margins.top = ConvertMilliInchToHundredThousanthMeter(new_margins.top);
cmm_margins.right =
ConvertMilliInchToHundredThousanthMeter(new_margins.right);
cmm_margins.bottom =
ConvertMilliInchToHundredThousanthMeter(new_margins.bottom);
UpdateMarginsMetric(cmm_margins);
}
void PrintSettings::RenderParams(PrintParams* params) const {
DCHECK(params);
params->printable_size.SetSize(page_setup_pixels_.content_area().width(),
page_setup_pixels_.content_area().height());
params->dpi = dpi_;
// Currently hardcoded at 1.25. See PrintSettings' constructor.
params->min_shrink = min_shrink;
// Currently hardcoded at 2.0. See PrintSettings' constructor.
params->max_shrink = max_shrink;
// Currently hardcoded at 72dpi. See PrintSettings' constructor.
params->desired_dpi = desired_dpi;
// Always use an invalid cookie.
params->document_cookie = 0;
}
bool PrintSettings::Equals(const PrintSettings& rhs) const {
// Do not test the display device name (printer_name_) for equality since it
// may sometimes be chopped off at 30 chars. As long as device_name is the
// same, that's fine.
return ranges == rhs.ranges &&
min_shrink == rhs.min_shrink &&
max_shrink == rhs.max_shrink &&
desired_dpi == rhs.desired_dpi &&
device_name_ == rhs.device_name_ &&
page_setup_pixels_.Equals(rhs.page_setup_pixels_) &&
page_setup_cmm_.Equals(rhs.page_setup_cmm_) &&
dpi_ == rhs.dpi_ &&
landscape_ == rhs.landscape_;
}
int PrintSettings::NewCookie() {
// A cookie of 0 is used to mark a document as unassigned, count from 1.
return cookie_seq.GetNext() + 1;
}
} // namespace printing

View File

@ -0,0 +1,141 @@
// 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.
#ifndef _PRINTING_PRINT_SETTINGS_H
#define _PRINTING_PRINT_SETTINGS_H
#include "page_range.h"
#include "page_setup.h"
#include "base/gfx/rect.h"
typedef struct HDC__* HDC;
typedef struct _devicemodeW DEVMODE;
namespace printing {
// Parameters for a render request.
struct PrintParams {
// In pixels according to dpi_x and dpi_y.
gfx::Size printable_size;
// Specifies dots per inch.
double dpi;
// Minimum shrink factor. See PrintSettings::min_shrink for more information.
double min_shrink;
// Maximum shrink factor. See PrintSettings::max_shrink for more information.
double max_shrink;
// Desired apparent dpi on paper.
int desired_dpi;
// Cookie for the document to ensure correctness.
int document_cookie;
// Warning: do not compare document_cookie.
bool Equals(const PrintParams& rhs) const {
return printable_size == rhs.printable_size &&
dpi == rhs.dpi &&
min_shrink == rhs.min_shrink &&
max_shrink == rhs.max_shrink &&
desired_dpi == rhs.desired_dpi;
}
};
// OS-independent print settings.
class PrintSettings {
public:
PrintSettings();
// Reinitialize the settings to the default values.
void Clear();
#ifdef WIN32
// Reads the settings from the selected device context. Calculates derived
// values like printable_area_.
void Init(HDC hdc,
const DEVMODE& dev_mode,
const PageRanges& new_ranges,
const std::wstring& new_device_name);
#endif
// Sets margins in 0.01 millimeter unit.
void UpdateMarginsMetric(const PageMargins& new_margins);
// Sets margins in thousandth of inch.
void UpdateMarginsMilliInch(const PageMargins& new_margins);
// Initializes the print parameters that needs to be sent to the renderer
// process.
void RenderParams(PrintParams* params) const;
// Equality operator.
// NOTE: printer_name is NOT tested for equality since it doesn't affect the
// output.
bool Equals(const PrintSettings& rhs) const;
const std::wstring& printer_name() const { return printer_name_; }
void set_device_name(const std::wstring& device_name) {
device_name_ = device_name;
}
const std::wstring& device_name() const { return device_name_; }
int dpi() const { return dpi_; }
const PageSetup& page_setup_cmm() const { return page_setup_cmm_; }
const PageSetup& page_setup_pixels() const { return page_setup_pixels_; }
// Multipage printing. Each PageRange describes a from-to page combinaison.
// This permits printing some selected pages only.
PageRanges ranges;
// By imaging to a width a little wider than the available pixels, thin pages
// will be scaled down a little, matching the way they print in IE and Camino.
// This lets them use fewer sheets than they would otherwise, which is
// presumably why other browsers do this. Wide pages will be scaled down more
// than this.
double min_shrink;
// This number determines how small we are willing to reduce the page content
// in order to accommodate the widest line. If the page would have to be
// reduced smaller to make the widest line fit, we just clip instead (this
// behavior matches MacIE and Mozilla, at least)
double max_shrink;
// Desired visible dots per inch rendering for output. Printing should be
// scaled to ScreenDpi/dpix*desired_dpi.
int desired_dpi;
// Cookie generator. It is used to initialize PrintedDocument with its
// associated PrintSettings, to be sure that each generated PrintedPage is
// correctly associated with its corresponding PrintedDocument.
static int NewCookie();
private:
//////////////////////////////////////////////////////////////////////////////
// Settings that can't be changed without side-effects.
// Printer name as shown to the user.
std::wstring printer_name_;
// Printer device name as opened by the OS.
std::wstring device_name_;
// Page setup in centimillimeter (0.01 mm) units.
PageSetup page_setup_cmm_;
// Page setup in pixel units, dpi adjusted.
PageSetup page_setup_pixels_;
// Printer's device effective dots per inch in both axis.
int dpi_;
// Is the orientation landscape or portrait.
bool landscape_;
};
} // namespace printing
#endif // _PRINTING_PRINT_SETTINGS_H

44
libcef/printing/units.cc Normal file
View File

@ -0,0 +1,44 @@
// 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 "precompiled_libcef.h"
#include "units.h"
#include "base/logging.h"
namespace printing {
int ConvertUnit(int value, int old_unit, int new_unit) {
DCHECK_GT(new_unit, 0);
DCHECK_GT(old_unit, 0);
// With integer arithmetic, to divide a value with correct rounding, you need
// to add half of the divisor value to the dividend value. You need to do the
// reverse with negative number.
if (value >= 0) {
return ((value * new_unit) + (old_unit / 2)) / old_unit;
} else {
return ((value * new_unit) - (old_unit / 2)) / old_unit;
}
}
double ConvertUnitDouble(double value, double old_unit, double new_unit) {
DCHECK_GT(new_unit, 0);
DCHECK_GT(old_unit, 0);
return value * new_unit / old_unit;
}
int ConvertMilliInchToHundredThousanthMeter(int milli_inch) {
// 1" == 25.4 mm
// 1" == 25400 um
// 0.001" == 25.4 um
// 0.001" == 2.54 cmm
return ConvertUnit(milli_inch, 100, 254);
}
int ConvertHundredThousanthMeterToMilliInch(int cmm) {
return ConvertUnit(cmm, 254, 100);
}
} // namespace printing

28
libcef/printing/units.h Normal file
View File

@ -0,0 +1,28 @@
// 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.
#ifndef _PRINTING_UNITS_H
#define _PRINTING_UNITS_H
namespace printing {
// Length of a thousanth of inches in 0.01mm unit.
const int kHundrethsMMPerInch = 2540;
// Converts from one unit system to another using integer arithmetics.
int ConvertUnit(int value, int old_unit, int new_unit);
// Converts from one unit system to another using doubles.
double ConvertUnitDouble(double value, double old_unit, double new_unit);
// Converts from 0.001 inch unit to 0.00001 meter.
int ConvertMilliInchToHundredThousanthMeter(int milli_inch);
// Converts from 0.00001 meter unit to 0.001 inch.
int ConvertHundredThousanthMeterToMilliInch(int cmm);
} // namespace printing
#endif // _PRINTING_UNITS_H

View File

@ -0,0 +1,479 @@
// 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 "precompiled_libcef.h"
#include "win_printing_context.h"
#include <winspool.h>
#include "base/file_util.h"
#include "base/gfx/platform_canvas.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
#include "base/time_format.h"
using base::Time;
namespace {
// Retrieves the content of a GetPrinter call.
void GetPrinterHelper(HANDLE printer, int level, scoped_array<uint8>* buffer) {
DWORD buf_size = 0;
GetPrinter(printer, level, NULL, 0, &buf_size);
if (buf_size) {
buffer->reset(new uint8[buf_size]);
memset(buffer->get(), 0, buf_size);
if (!GetPrinter(printer, level, buffer->get(), buf_size, &buf_size)) {
buffer->reset();
}
}
}
} // namespace
namespace printing {
PrintingContext::PrintingContext()
: hdc_(NULL),
#ifndef NDEBUG
page_number_(-1),
#endif
dialog_box_(NULL),
dialog_box_dismissed_(false),
abort_printing_(false),
in_print_job_(false) {
}
PrintingContext::~PrintingContext() {
ResetSettings();
}
PrintingContext::Result PrintingContext::AskUserForSettings(HWND window,
int max_pages) {
DCHECK(window);
DCHECK(!in_print_job_);
dialog_box_dismissed_ = false;
// Show the OS-dependent dialog box.
// If the user press
// - OK, the settings are reset and reinitialized with the new settings. OK is
// returned.
// - Apply then Cancel, the settings are reset and reinitialized with the new
// settings. CANCEL is returned.
// - Cancel, the settings are not changed, the previous setting, if it was
// initialized before, are kept. CANCEL is returned.
// On failure, the settings are reset and FAILED is returned.
PRINTDLGEX dialog_options = { sizeof(PRINTDLGEX) };
dialog_options.hwndOwner = window;
// Disables the Current Page and Selection radio buttons since WebKit can't
// print a part of the webpage and we don't know which page is the current
// one.
// TODO(maruel): Reuse the previously loaded settings!
dialog_options.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE |
PD_NOSELECTION | PD_NOCURRENTPAGE | PD_HIDEPRINTTOFILE;
PRINTPAGERANGE ranges[32];
dialog_options.nStartPage = START_PAGE_GENERAL;
if (max_pages) {
// Default initialize to print all the pages.
memset(ranges, 0, sizeof(ranges));
ranges[0].nFromPage = 1;
ranges[0].nToPage = max_pages;
dialog_options.nPageRanges = 1;
dialog_options.nMaxPageRanges = arraysize(ranges);
dialog_options.nMaxPage = max_pages;
dialog_options.lpPageRanges = ranges;
} else {
// No need to bother, we don't know how many pages are available.
dialog_options.Flags |= PD_NOPAGENUMS;
}
{
if (PrintDlgEx(&dialog_options) != S_OK) {
ResetSettings();
return FAILED;
}
}
// TODO(maruel): Support PD_PRINTTOFILE.
return ParseDialogResultEx(dialog_options);
}
PrintingContext::Result PrintingContext::UseDefaultSettings() {
DCHECK(!in_print_job_);
PRINTDLG dialog_options = { sizeof(PRINTDLG) };
dialog_options.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
if (PrintDlg(&dialog_options) == 0) {
ResetSettings();
return FAILED;
}
return ParseDialogResult(dialog_options);
}
PrintingContext::Result PrintingContext::InitWithSettings(
const PrintSettings& settings) {
DCHECK(!in_print_job_);
settings_ = settings;
// TODO(maruel): settings_->ToDEVMODE()
HANDLE printer;
if (!OpenPrinter(const_cast<wchar_t*>(settings_.device_name().c_str()),
&printer,
NULL))
return FAILED;
Result status = OK;
if (!GetPrinterSettings(printer, settings_.device_name()))
status = FAILED;
// Close the printer after retrieving the context.
ClosePrinter(printer);
if (status != OK)
ResetSettings();
return status;
}
void PrintingContext::ResetSettings() {
if (hdc_ != NULL) {
DeleteDC(hdc_);
hdc_ = NULL;
}
settings_.Clear();
in_print_job_ = false;
#ifndef NDEBUG
page_number_ = -1;
#endif
}
PrintingContext::Result PrintingContext::NewDocument(
const std::wstring& document_name) {
DCHECK(!in_print_job_);
if (!hdc_)
return OnErrror();
// Set the flag used by the AbortPrintJob dialog procedure.
abort_printing_ = false;
in_print_job_ = true;
// Register the application's AbortProc function with GDI.
if (SP_ERROR == SetAbortProc(hdc_, &AbortProc))
return OnErrror();
DOCINFO di = { sizeof(DOCINFO) };
di.lpszDocName = document_name.c_str();
DCHECK_EQ(MessageLoop::current()->NestableTasksAllowed(), false);
// Begin a print job by calling the StartDoc function.
// NOTE: StartDoc() starts a message loop. That causes a lot of problems with
// IPC. Make sure recursive task processing is disabled.
if (StartDoc(hdc_, &di) <= 0)
return OnErrror();
#ifndef NDEBUG
page_number_ = 0;
#endif
return OK;
}
PrintingContext::Result PrintingContext::NewPage() {
if (abort_printing_)
return CANCEL;
DCHECK(in_print_job_);
// Inform the driver that the application is about to begin sending data.
if (StartPage(hdc_) <= 0)
return OnErrror();
#ifndef NDEBUG
++page_number_;
#endif
return OK;
}
PrintingContext::Result PrintingContext::PageDone() {
if (abort_printing_)
return CANCEL;
DCHECK(in_print_job_);
if (EndPage(hdc_) <= 0)
return OnErrror();
return OK;
}
PrintingContext::Result PrintingContext::DocumentDone() {
if (abort_printing_)
return CANCEL;
DCHECK(in_print_job_);
// Inform the driver that document has ended.
if (EndDoc(hdc_) <= 0)
return OnErrror();
ResetSettings();
return OK;
}
void PrintingContext::Cancel() {
abort_printing_ = true;
in_print_job_ = false;
if (hdc_)
CancelDC(hdc_);
DismissDialog();
}
void PrintingContext::DismissDialog() {
if (dialog_box_) {
DestroyWindow(dialog_box_);
dialog_box_dismissed_ = true;
}
}
PrintingContext::Result PrintingContext::OnErrror() {
// This will close hdc_ and clear settings_.
ResetSettings();
return abort_printing_ ? CANCEL : FAILED;
}
// static
BOOL PrintingContext::AbortProc(HDC hdc, int nCode) {
if (nCode) {
// TODO(maruel): Need a way to find the right instance to set. Should
// leverage PrintJobManager here?
// abort_printing_ = true;
}
return true;
}
bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode,
const std::wstring& new_device_name,
const PRINTPAGERANGE* ranges,
int number_ranges) {
gfx::PlatformDeviceWin::InitializeDC(hdc_);
DCHECK(GetDeviceCaps(hdc_, CLIPCAPS));
DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_STRETCHDIB);
DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_BITMAP64);
// Some printers don't advertise these.
// DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_SCALING);
// DCHECK(GetDeviceCaps(hdc_, SHADEBLENDCAPS) & SB_CONST_ALPHA);
// DCHECK(GetDeviceCaps(hdc_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA);
// StretchDIBits() support is needed for printing.
if (!(GetDeviceCaps(hdc_, RASTERCAPS) & RC_STRETCHDIB) ||
!(GetDeviceCaps(hdc_, RASTERCAPS) & RC_BITMAP64)) {
NOTREACHED();
ResetSettings();
return false;
}
DCHECK(!in_print_job_);
DCHECK(hdc_);
// Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector.
PageRanges ranges_vector;
ranges_vector.reserve(number_ranges);
for (int i = 0; i < number_ranges; ++i) {
PageRange range;
// Transfert from 1-based to 0-based.
range.from = ranges[i].nFromPage - 1;
range.to = ranges[i].nToPage - 1;
ranges_vector.push_back(range);
}
settings_.Init(hdc_, dev_mode, ranges_vector, new_device_name);
PageMargins margins;
margins.header = 500;
margins.footer = 500;
margins.left = 500;
margins.top = 500;
margins.right = 500;
margins.bottom = 500;
settings_.UpdateMarginsMilliInch(margins);
return true;
}
bool PrintingContext::GetPrinterSettings(HANDLE printer,
const std::wstring& device_name) {
DCHECK(!in_print_job_);
scoped_array<uint8> buffer;
// A PRINTER_INFO_9 structure specifying the per-user default printer
// settings.
GetPrinterHelper(printer, 9, &buffer);
if (buffer.get()) {
PRINTER_INFO_9* info_9 = reinterpret_cast<PRINTER_INFO_9*>(buffer.get());
if (info_9->pDevMode != NULL) {
if (!AllocateContext(device_name, info_9->pDevMode)) {
ResetSettings();
return false;
}
return InitializeSettings(*info_9->pDevMode, device_name, NULL, 0);
}
buffer.reset();
}
// A PRINTER_INFO_8 structure specifying the global default printer settings.
GetPrinterHelper(printer, 8, &buffer);
if (buffer.get()) {
PRINTER_INFO_8* info_8 = reinterpret_cast<PRINTER_INFO_8*>(buffer.get());
if (info_8->pDevMode != NULL) {
if (!AllocateContext(device_name, info_8->pDevMode)) {
ResetSettings();
return false;
}
return InitializeSettings(*info_8->pDevMode, device_name, NULL, 0);
}
buffer.reset();
}
// A PRINTER_INFO_2 structure specifying the driver's default printer
// settings.
GetPrinterHelper(printer, 2, &buffer);
if (buffer.get()) {
PRINTER_INFO_2* info_2 = reinterpret_cast<PRINTER_INFO_2*>(buffer.get());
if (info_2->pDevMode != NULL) {
if (!AllocateContext(device_name, info_2->pDevMode)) {
ResetSettings();
return false;
}
return InitializeSettings(*info_2->pDevMode, device_name, NULL, 0);
}
buffer.reset();
}
// Failed to retrieve the printer settings.
ResetSettings();
return false;
}
bool PrintingContext::AllocateContext(const std::wstring& printer_name,
const DEVMODE* dev_mode) {
hdc_ = CreateDC(L"WINSPOOL", printer_name.c_str(), NULL, dev_mode);
DCHECK(hdc_);
return hdc_ != NULL;
}
PrintingContext::Result PrintingContext::ParseDialogResultEx(
const PRINTDLGEX& dialog_options) {
// If the user clicked OK or Apply then Cancel, but not only Cancel.
if (dialog_options.dwResultAction != PD_RESULT_CANCEL) {
// Start fresh.
ResetSettings();
DEVMODE* dev_mode = NULL;
if (dialog_options.hDevMode) {
dev_mode =
reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode));
DCHECK(dev_mode);
}
std::wstring device_name;
if (dialog_options.hDevNames) {
DEVNAMES* dev_names =
reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames));
DCHECK(dev_names);
if (dev_names) {
device_name =
reinterpret_cast<const wchar_t*>(
reinterpret_cast<const wchar_t*>(dev_names) +
dev_names->wDeviceOffset);
GlobalUnlock(dialog_options.hDevNames);
}
}
bool success = false;
if (dev_mode && !device_name.empty()) {
hdc_ = dialog_options.hDC;
if (dialog_options.Flags & PD_PAGENUMS) {
success = InitializeSettings(*dev_mode,
device_name,
dialog_options.lpPageRanges,
dialog_options.nPageRanges);
} else {
success = InitializeSettings(*dev_mode, device_name, NULL, 0);
}
}
if (!success && dialog_options.hDC) {
DeleteDC(dialog_options.hDC);
hdc_ = NULL;
}
if (dev_mode) {
GlobalUnlock(dialog_options.hDevMode);
}
} else {
if (dialog_options.hDC) {
DeleteDC(dialog_options.hDC);
}
}
if (dialog_options.hDevMode != NULL)
GlobalFree(dialog_options.hDevMode);
if (dialog_options.hDevNames != NULL)
GlobalFree(dialog_options.hDevNames);
switch (dialog_options.dwResultAction) {
case PD_RESULT_PRINT:
return hdc_ ? OK : FAILED;
case PD_RESULT_APPLY:
return hdc_ ? CANCEL : FAILED;
case PD_RESULT_CANCEL:
return CANCEL;
default:
return FAILED;
}
}
PrintingContext::Result PrintingContext::ParseDialogResult(
const PRINTDLG& dialog_options) {
// If the user clicked OK or Apply then Cancel, but not only Cancel.
// Start fresh.
ResetSettings();
DEVMODE* dev_mode = NULL;
if (dialog_options.hDevMode) {
dev_mode =
reinterpret_cast<DEVMODE*>(GlobalLock(dialog_options.hDevMode));
DCHECK(dev_mode);
}
std::wstring device_name;
if (dialog_options.hDevNames) {
DEVNAMES* dev_names =
reinterpret_cast<DEVNAMES*>(GlobalLock(dialog_options.hDevNames));
DCHECK(dev_names);
if (dev_names) {
device_name =
reinterpret_cast<const wchar_t*>(
reinterpret_cast<const wchar_t*>(dev_names) +
dev_names->wDeviceOffset);
GlobalUnlock(dialog_options.hDevNames);
}
}
bool success = false;
if (dev_mode && !device_name.empty()) {
hdc_ = dialog_options.hDC;
success = InitializeSettings(*dev_mode, device_name, NULL, 0);
}
if (!success && dialog_options.hDC) {
DeleteDC(dialog_options.hDC);
hdc_ = NULL;
}
if (dev_mode) {
GlobalUnlock(dialog_options.hDevMode);
}
if (dialog_options.hDevMode != NULL)
GlobalFree(dialog_options.hDevMode);
if (dialog_options.hDevNames != NULL)
GlobalFree(dialog_options.hDevNames);
return hdc_ ? OK : FAILED;
}
} // namespace printing

View File

@ -0,0 +1,139 @@
// 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.
#ifndef _PRINTING_WIN_PRINTING_CONTEXT_H
#define _PRINTING_WIN_PRINTING_CONTEXT_H
#include "print_settings.h"
#include <ocidl.h>
#include <commdlg.h>
#include <string>
#include "base/basictypes.h"
namespace printing {
// Describe the user selected printing context for Windows. This includes the
// OS-dependent UI to ask the user about the print settings. This class directly
// talk to the printer and manages the document and pages breaks.
class PrintingContext {
public:
// Tri-state result for user behavior-dependent functions.
enum Result {
OK,
CANCEL,
FAILED,
};
PrintingContext();
~PrintingContext();
// Asks the user what printer and format should be used to print. Updates the
// context with the select device settings.
Result AskUserForSettings(HWND window, int max_pages);
// Selects the user's default printer and format. Updates the context with the
// default device settings.
Result UseDefaultSettings();
// Initializes with predefined settings.
Result InitWithSettings(const PrintSettings& settings);
// Reinitializes the settings to uninitialized for object reuse.
void ResetSettings();
// Does platform specific setup of the printer before the printing. Signal the
// printer that a document is about to be spooled.
// Warning: This function enters a message loop. That may cause side effects
// like IPC message processing! Some printers have side-effects on this call
// like virtual printers that ask the user for the path of the saved document;
// for example a PDF printer.
Result NewDocument(const std::wstring& document_name);
// Starts a new page.
Result NewPage();
// Closes the printed page.
Result PageDone();
// Closes the printing job. After this call the object is ready to start a new
// document.
Result DocumentDone();
// Cancels printing. Can be used in a multithreaded context. Takes effect
// immediately.
void Cancel();
// Dismiss the Print... dialog box if shown.
void DismissDialog();
HDC context() {
return hdc_;
}
const PrintSettings& settings() const {
return settings_;
}
private:
// Class that manages the PrintDlgEx() callbacks. This is meant to be a
// temporary object used during the Print... dialog display.
class CallbackHandler;
// Does bookeeping when an error occurs.
PrintingContext::Result OnErrror();
// Used in response to the user cancelling the printing.
static BOOL CALLBACK AbortProc(HDC hdc, int nCode);
// Reads the settings from the selected device context. Updates settings_ and
// its margins.
bool InitializeSettings(const DEVMODE& dev_mode,
const std::wstring& new_device_name,
const PRINTPAGERANGE* ranges,
int number_ranges);
// Retrieves the printer's default low-level settings. hdc_ is allocated with
// this call.
bool GetPrinterSettings(HANDLE printer,
const std::wstring& device_name);
// Allocates the HDC for a specific DEVMODE.
bool AllocateContext(const std::wstring& printer_name,
const DEVMODE* dev_mode);
// Parses the result of a PRINTDLGEX result.
Result ParseDialogResultEx(const PRINTDLGEX& dialog_options);
Result ParseDialogResult(const PRINTDLG& dialog_options);
// The selected printer context.
HDC hdc_;
// Complete print context settings.
PrintSettings settings_;
#ifndef NDEBUG
// Current page number in the print job.
int page_number_;
#endif
// The dialog box for the time it is shown.
volatile HWND dialog_box_;
// The dialog box has been dismissed.
volatile bool dialog_box_dismissed_;
// Is a print job being done.
volatile bool in_print_job_;
// Did the user cancel the print job.
volatile bool abort_printing_;
DISALLOW_EVIL_CONSTRUCTORS(PrintingContext);
};
} // namespace printing
#endif // _PRINTING_WIN_PRINTING_CONTEXT_H

398
libcef/request_impl.cc Normal file
View File

@ -0,0 +1,398 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "request_impl.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "webkit/glue/glue_util.h"
CefRefPtr<CefRequest> CefRequest::CreateRequest()
{
CefRefPtr<CefRequest> request(new CefRequestImpl());
return request;
}
CefRequestImpl::CefRequestImpl()
{
}
CefRequestImpl::~CefRequestImpl()
{
}
std::wstring CefRequestImpl::GetURL()
{
Lock();
std::wstring url = url_;
Unlock();
return url;
}
void CefRequestImpl::SetURL(const std::wstring& url)
{
Lock();
url_ = url;
Unlock();
}
std::wstring CefRequestImpl::GetFrame()
{
Lock();
std::wstring frame = frame_;
Unlock();
return frame;
}
void CefRequestImpl::SetFrame(const std::wstring& url)
{
Lock();
frame_ = url;
Unlock();
}
std::wstring CefRequestImpl::GetMethod()
{
Lock();
std::wstring method = method_;
Unlock();
return method;
}
void CefRequestImpl::SetMethod(const std::wstring& method)
{
Lock();
method_ = method;
Unlock();
}
CefRefPtr<CefPostData> CefRequestImpl::GetPostData()
{
Lock();
CefRefPtr<CefPostData> postData = postdata_;
Unlock();
return postData;
}
void CefRequestImpl::SetPostData(CefRefPtr<CefPostData> postData)
{
Lock();
postdata_ = postData;
Unlock();
}
void CefRequestImpl::GetHeaderMap(HeaderMap& headerMap)
{
Lock();
headerMap = headermap_;
Unlock();
}
void CefRequestImpl::SetHeaderMap(const HeaderMap& headerMap)
{
Lock();
headermap_ = headerMap;
Unlock();
}
void CefRequestImpl::Set(const std::wstring& url,
const std::wstring& frame,
const std::wstring& method,
CefRefPtr<CefPostData> postData,
const HeaderMap& headerMap)
{
Lock();
url_ = url;
frame_ = frame;
method_ = method;
postdata_ = postData;
headermap_ = headerMap;
Unlock();
}
void CefRequestImpl::SetHeaderMap(const WebRequest::HeaderMap& map)
{
Lock();
WebRequest::HeaderMap::const_iterator it = map.begin();
for(; it != map.end(); ++it) {
headermap_.insert(
std::make_pair(
UTF8ToWide(it->first.c_str()),
UTF8ToWide(it->second.c_str())));
}
Unlock();
}
void CefRequestImpl::GetHeaderMap(WebRequest::HeaderMap& map)
{
Lock();
HeaderMap::const_iterator it = headermap_.begin();
for(; it != headermap_.end(); ++it) {
map.insert(
std::make_pair(
WideToUTF8(it->first.c_str()),
WideToUTF8(it->second.c_str())));
}
Unlock();
}
CefRefPtr<CefPostData> CefPostData::CreatePostData()
{
CefRefPtr<CefPostData> postdata(new CefPostDataImpl());
return postdata;
}
CefPostDataImpl::CefPostDataImpl()
{
}
CefPostDataImpl::~CefPostDataImpl()
{
RemoveElements();
}
size_t CefPostDataImpl::GetElementCount()
{
Lock();
size_t ct = elements_.size();
Unlock();
return ct;
}
void CefPostDataImpl::GetElements(ElementVector& elements)
{
Lock();
elements = elements_;
Unlock();
}
bool CefPostDataImpl::RemoveElement(CefRefPtr<CefPostDataElement> element)
{
bool deleted = false;
Lock();
ElementVector::iterator it = elements_.begin();
for(; it != elements_.end(); ++it) {
if(it->get() == element.get()) {
elements_.erase(it);
deleted = true;
break;
}
}
Unlock();
return deleted;
}
bool CefPostDataImpl::AddElement(CefRefPtr<CefPostDataElement> element)
{
bool found = false;
Lock();
// check that the element isn't already in the list before adding
ElementVector::const_iterator it = elements_.begin();
for(; it != elements_.end(); ++it) {
if(it->get() == element.get()) {
found = true;
break;
}
}
if(!found)
elements_.push_back(element);
Unlock();
return !found;
}
void CefPostDataImpl::RemoveElements()
{
Lock();
elements_.clear();
Unlock();
}
void CefPostDataImpl::Set(const net::UploadData& data)
{
Lock();
CefRefPtr<CefPostDataElement> postelem;
const std::vector<net::UploadData::Element>& elements = data.elements();
std::vector<net::UploadData::Element>::const_iterator it = elements.begin();
for (; it != elements.end(); ++it) {
postelem = CefPostDataElement::CreatePostDataElement();
static_cast<CefPostDataElementImpl*>(postelem.get())->Set(*it);
AddElement(postelem);
}
Unlock();
}
void CefPostDataImpl::Get(net::UploadData& data)
{
Lock();
net::UploadData::Element* element;
ElementVector::iterator it = elements_.begin();
for(; it != elements_.end(); ++it) {
element = new net::UploadData::Element();
static_cast<CefPostDataElementImpl*>(it->get())->Set(*element);
}
Unlock();
}
CefRefPtr<CefPostDataElement> CefPostDataElement::CreatePostDataElement()
{
CefRefPtr<CefPostDataElement> element(new CefPostDataElementImpl());
return element;
}
CefPostDataElementImpl::CefPostDataElementImpl()
{
type_ = TYPE_EMPTY;
}
CefPostDataElementImpl::~CefPostDataElementImpl()
{
SetToEmpty();
}
void CefPostDataElementImpl::SetToEmpty()
{
Lock();
if(type_ == TYPE_BYTES)
free(data_.bytes.bytes);
else if(type_ == TYPE_FILE)
free(data_.filename);
type_ = TYPE_EMPTY;
Unlock();
}
void CefPostDataElementImpl::SetToFile(const std::wstring& fileName)
{
Lock();
// Clear any data currently in the element
SetToEmpty();
// Assign the new file name
size_t size = fileName.size();
wchar_t* data = static_cast<wchar_t*>(malloc((size + 1) * sizeof(wchar_t)));
DCHECK(data != NULL);
if(data == NULL)
return;
memcpy(static_cast<void*>(data), static_cast<const void*>(fileName.c_str()),
size * sizeof(wchar_t));
data[size] = 0;
// Assign the new data
type_ = TYPE_FILE;
data_.filename = data;
Unlock();
}
void CefPostDataElementImpl::SetToBytes(size_t size, const void* bytes)
{
Lock();
// Clear any data currently in the element
SetToEmpty();
// Assign the new data
void* data = malloc(size);
DCHECK(data != NULL);
if(data == NULL)
return;
memcpy(data, bytes, size);
type_ = TYPE_BYTES;
data_.bytes.bytes = data;
data_.bytes.size = size;
Unlock();
}
CefPostDataElement::Type CefPostDataElementImpl::GetType()
{
Lock();
CefPostDataElement::Type type = type_;
Unlock();
return type;
}
std::wstring CefPostDataElementImpl::GetFile()
{
Lock();
DCHECK(type_ == TYPE_FILE);
std::wstring filename;
if(type_ == TYPE_FILE)
filename = data_.filename;
Unlock();
return filename;
}
size_t CefPostDataElementImpl::GetBytesCount()
{
Lock();
DCHECK(type_ == TYPE_BYTES);
size_t size = 0;
if(type_ == TYPE_BYTES)
size = data_.bytes.size;
Unlock();
return size;
}
size_t CefPostDataElementImpl::GetBytes(size_t size, void *bytes)
{
Lock();
DCHECK(type_ == TYPE_BYTES);
size_t rv = 0;
if(type_ == TYPE_BYTES) {
rv = (size < data_.bytes.size ? size : data_.bytes.size);
memcpy(bytes, data_.bytes.bytes, rv);
}
Unlock();
return rv;
}
void CefPostDataElementImpl::Set(const net::UploadData::Element& element)
{
Lock();
if (element.type() == net::UploadData::TYPE_BYTES) {
SetToBytes(element.bytes().size(),
static_cast<const void*>(
std::string(element.bytes().begin(),
element.bytes().end()).c_str()));
} else if (element.type() == net::UploadData::TYPE_FILE) {
SetToFile(element.file_path());
} else {
NOTREACHED();
}
Unlock();
}
void CefPostDataElementImpl::Get(net::UploadData::Element& element)
{
Lock();
if(type_ == TYPE_BYTES) {
element.SetToBytes(static_cast<char*>(data_.bytes.bytes), data_.bytes.size);
} else if(type_ == TYPE_FILE) {
element.SetToFilePath(data_.filename);
} else {
NOTREACHED();
}
Unlock();
}

96
libcef/request_impl.h Normal file
View File

@ -0,0 +1,96 @@
// Copyright (c) 2008 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.
#ifndef _REQUEST_IMPL_H
#define _REQUEST_IMPL_H
#include "../include/cef.h"
#include "net/base/upload_data.h"
#include "webkit/glue/weburlrequest.h"
// Implementation of CefRequest
class CefRequestImpl : public CefThreadSafeBase<CefRequest>
{
public:
CefRequestImpl();
~CefRequestImpl();
virtual std::wstring GetURL();
virtual void SetURL(const std::wstring& url);
virtual std::wstring GetFrame();
virtual void SetFrame(const std::wstring& url);
virtual std::wstring GetMethod();
virtual void SetMethod(const std::wstring& method);
virtual CefRefPtr<CefPostData> GetPostData();
virtual void SetPostData(CefRefPtr<CefPostData> postData);
virtual void GetHeaderMap(HeaderMap& headerMap);
virtual void SetHeaderMap(const HeaderMap& headerMap);
virtual void Set(const std::wstring& url,
const std::wstring& frame,
const std::wstring& method,
CefRefPtr<CefPostData> postData,
const HeaderMap& headerMap);
void SetHeaderMap(const WebRequest::HeaderMap& map);
void GetHeaderMap(WebRequest::HeaderMap& map);
protected:
std::wstring url_;
std::wstring frame_;
std::wstring method_;
CefRefPtr<CefPostData> postdata_;
HeaderMap headermap_;
};
// Implementation of CefPostData
class CefPostDataImpl : public CefThreadSafeBase<CefPostData>
{
public:
CefPostDataImpl();
~CefPostDataImpl();
virtual size_t GetElementCount();
virtual void GetElements(ElementVector& elements);
virtual bool RemoveElement(CefRefPtr<CefPostDataElement> element);
virtual bool AddElement(CefRefPtr<CefPostDataElement> element);
virtual void RemoveElements();
void Set(const net::UploadData& data);
void Get(net::UploadData& data);
protected:
ElementVector elements_;
};
// Implementation of CefPostDataElement
class CefPostDataElementImpl : public CefThreadSafeBase<CefPostDataElement>
{
public:
CefPostDataElementImpl();
~CefPostDataElementImpl();
virtual void SetToEmpty();
virtual void SetToFile(const std::wstring& fileName);
virtual void SetToBytes(size_t size, const void* bytes);
virtual Type GetType();
virtual std::wstring GetFile();
virtual size_t GetBytesCount();
virtual size_t GetBytes(size_t size, void *bytes);
void Set(const net::UploadData::Element& element);
void Get(net::UploadData::Element& element);
protected:
Type type_;
union {
struct {
void* bytes;
size_t size;
} bytes;
wchar_t* filename;
} data_;
};
#endif // _REQUEST_IMPL_H

323
libcef/stream_impl.cc Normal file
View File

@ -0,0 +1,323 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "stream_impl.h"
#include "base/logging.h"
// Static functions
CefRefPtr<CefStreamReader> CefStreamReader::CreateForFile(const std::wstring& fileName)
{
CefRefPtr<CefStreamReader> reader;
FILE *f = _wfopen(fileName.c_str(), L"rb");
if(f)
reader = new CefFileReader(f, true);
return reader;
}
CefRefPtr<CefStreamReader> CefStreamReader::CreateForData(void *data, size_t size)
{
DCHECK(data != NULL);
DCHECK(size > 0);
CefRefPtr<CefStreamReader> reader;
if(data && size > 0)
reader = new CefBytesReader(data, size, true);
return reader;
}
// CefFileReader
CefFileReader::CefFileReader(FILE* file, bool close)
: file_(file), close_(close)
{
}
CefFileReader::~CefFileReader()
{
Lock();
if(close_)
fclose(file_);
Unlock();
}
size_t CefFileReader::Read(void *ptr, size_t size, size_t n)
{
Lock();
size_t rv = fread(ptr, size, n, file_);
Unlock();
return rv;
}
int CefFileReader::Seek(long offset, int whence)
{
Lock();
int rv = fseek(file_, offset, whence);
Unlock();
return rv;
}
long CefFileReader::Tell()
{
Lock();
long rv = ftell(file_);
Unlock();
return rv;
}
int CefFileReader::Eof()
{
Lock();
int rv = feof(file_);
Unlock();
return rv;
}
// CefFileWriter
CefFileWriter::CefFileWriter(FILE* file, bool close)
: file_(file), close_(close)
{
}
CefFileWriter::~CefFileWriter()
{
Lock();
if(close_)
fclose(file_);
Unlock();
}
size_t CefFileWriter::Write(const void *ptr, size_t size, size_t n)
{
Lock();
size_t rv = (size_t)fwrite(ptr, size, n, file_);
Unlock();
return rv;
}
int CefFileWriter::Seek(long offset, int whence)
{
Lock();
int rv = fseek(file_, offset, whence);
Unlock();
return rv;
}
long CefFileWriter::Tell()
{
Lock();
long rv = ftell(file_);
Unlock();
return rv;
}
int CefFileWriter::Flush()
{
Lock();
int rv = fflush(file_);
Unlock();
return rv;
}
// CefBytesReader
CefBytesReader::CefBytesReader(void *data, long datasize, bool copy)
: data_(NULL), datasize_(0), copy_(false), offset_(0)
{
SetData(data, datasize, copy);
}
CefBytesReader::~CefBytesReader()
{
SetData(NULL, 0, false);
}
size_t CefBytesReader::Read(void *ptr, size_t size, size_t n)
{
Lock();
size_t s = (datasize_ - offset_) / size;
size_t ret = (n < s ? n : s);
memcpy(ptr, ((char*)data_) + offset_, ret * size);
offset_ += ret * size;
Unlock();
return ret;
}
int CefBytesReader::Seek(long offset, int whence)
{
int rv = -1L;
Lock();
switch(whence) {
case SEEK_CUR:
if(offset_ + offset > datasize_) {
break;
}
offset_ += offset;
rv = offset_;
break;
case SEEK_END:
if(offset > (int)datasize_) {
break;
}
offset_ = datasize_ - offset;
rv = offset_;
case SEEK_SET:
if(offset > (int)datasize_) {
break;
}
offset_ = offset;
rv = offset_;
break;
}
Unlock();
return rv;
}
long CefBytesReader::Tell()
{
Lock();
long rv = offset_;
Unlock();
return rv;
}
int CefBytesReader::Eof()
{
Lock();
int rv = (offset_ >= datasize_);
Unlock();
return rv;
}
void CefBytesReader::SetData(void *data, long datasize, bool copy)
{
Lock();
if(copy_)
free(data_);
copy_ = copy;
offset_ = 0;
datasize_ = datasize;
if(copy) {
data_ = malloc(datasize);
DCHECK(data_ != NULL);
if(data_)
memcpy(data_, data, datasize);
} else {
data_ = data;
}
Unlock();
}
// CefBytesWriter
CefBytesWriter::CefBytesWriter(size_t grow)
: grow_(grow), offset_(0), datasize_(grow)
{
DCHECK(grow > 0);
data_ = malloc(grow);
DCHECK(data_ != NULL);
}
CefBytesWriter::~CefBytesWriter()
{
Lock();
if(data_)
free(data_);
Unlock();
}
size_t CefBytesWriter::Write(const void *ptr, size_t size, size_t n)
{
Lock();
size_t rv;
if(offset_ + size * n >= datasize_ && Grow(size * n) == 0) {
rv = 0;
} else {
memcpy(((char*)data_) + offset_, ptr, size * n);
offset_ += size * n;
rv = n;
}
Unlock();
return rv;
}
int CefBytesWriter::Seek(long offset, int whence)
{
int rv = -1L;
Lock();
switch(whence) {
case SEEK_CUR:
if(offset_ + offset > datasize_) {
break;
}
offset_ += offset;
rv = offset_;
break;
case SEEK_END:
if(offset > (int)datasize_) {
break;
}
offset_ = datasize_ - offset;
rv = offset_;
case SEEK_SET:
if(offset > (int)datasize_) {
break;
}
offset_ = offset;
rv = offset_;
break;
}
Unlock();
return rv;
}
long CefBytesWriter::Tell()
{
Lock();
long rv = offset_;
Unlock();
return rv;
}
int CefBytesWriter::Flush()
{
return 0;
}
std::string CefBytesWriter::GetDataString()
{
Lock();
std::string str((char*)data_, datasize_);
Unlock();
return str;
}
size_t CefBytesWriter::Grow(size_t size)
{
Lock();
size_t rv;
size_t s = (size > grow_ ? size : grow_);
void *tmp = realloc(data_, datasize_ + s);
DCHECK(tmp != NULL);
if(tmp) {
data_ = tmp;
datasize_ += s;
rv = datasize_;
} else {
rv = 0;
}
Unlock();
return rv;
}

95
libcef/stream_impl.h Normal file
View File

@ -0,0 +1,95 @@
// Copyright (c) 2008 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.
#ifndef _STREAM_IMPL_H
#define _STREAM_IMPL_H
#include "../include/cef.h"
#include <stdio.h>
// Implementation of CefStreamReader for files.
class CefFileReader : public CefThreadSafeBase<CefStreamReader>
{
public:
CefFileReader(FILE* file, bool close);
~CefFileReader();
virtual size_t Read(void *ptr, size_t size, size_t n);
virtual int Seek(long offset, int whence);
virtual long Tell();
virtual int Eof();
protected:
bool close_;
FILE *file_;
};
// Implementation of CefStreamWriter for files.
class CefFileWriter : public CefThreadSafeBase<CefStreamWriter>
{
public:
CefFileWriter(FILE* file, bool close);
~CefFileWriter();
virtual size_t Write(const void *ptr, size_t size, size_t n);
virtual int Seek(long offset, int whence);
virtual long Tell();
virtual int Flush();
protected:
FILE *file_;
bool close_;
};
// Implementation of CefStreamReader for byte buffers.
class CefBytesReader : public CefThreadSafeBase<CefStreamReader>
{
public:
CefBytesReader(void *data, long datasize, bool copy);
~CefBytesReader();
virtual size_t Read(void *ptr, size_t size, size_t n);
virtual int Seek(long offset, int whence);
virtual long Tell();
virtual int Eof();
void SetData(void *data, long datasize, bool copy);
void *GetData() { return data_; }
size_t GetDataSize() { return offset_; }
protected:
void *data_;
size_t datasize_;
bool copy_;
size_t offset_;
};
// Implementation of CefStreamWriter for byte buffers.
class CefBytesWriter : public CefThreadSafeBase<CefStreamWriter>
{
public:
CefBytesWriter(size_t grow);
~CefBytesWriter();
virtual size_t Write(const void *ptr, size_t size, size_t n);
virtual int Seek(long offset, int whence);
virtual long Tell();
virtual int Flush();
void *GetData() { return data_; }
size_t GetDataSize() { return offset_; }
std::string GetDataString();
protected:
size_t Grow(size_t size);
protected:
size_t grow_;
void *data_;
size_t datasize_;
size_t offset_;
};
#endif // _STREAM_IMPL_H

361
libcef/variant_impl.cc Normal file
View File

@ -0,0 +1,361 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "variant_impl.h"
#include "variant_np_util.h"
#include "base/compiler_specific.h"
#include "config.h"
MSVC_PUSH_WARNING_LEVEL(0);
#include "DOMWindow.h"
#include "Frame.h"
#include "npruntime_priv.h" // for NPN_InitializeVariantWithStringCopy
MSVC_POP_WARNING();
#undef LOG
#include "base/logging.h"
#include "base/string_util.h"
#include "webkit/glue/webframe.h"
CefVariantImpl::CefVariantImpl()
{
variant_.type = NPVariantType_Null;
webframe_ = NULL;
}
CefVariantImpl::CefVariantImpl(WebFrame *webframe)
{
variant_.type = NPVariantType_Null;
webframe_ = webframe;
}
// Note that Set() performs a deep copy, which is necessary to safely
// call SetNull() on the value in the destructor.
CefVariantImpl::CefVariantImpl(const CefVariantImpl& original)
{
Lock();
variant_.type = NPVariantType_Null;
Set(*original.GetNPVariant());
Unlock();
}
// See comment for copy constructor, above.
CefVariantImpl& CefVariantImpl::operator=(const CefVariantImpl& original)
{
if (&original != this) {
Lock();
Set(*original.GetNPVariant());
Unlock();
}
return *this;
}
CefVariantImpl::~CefVariantImpl()
{
SetNull();
}
CefVariant::Type CefVariantImpl::GetType()
{
CefVariant::Type type = TYPE_NULL;
Lock();
// determine the data type of the underlying NPVariant value
switch (variant_.type) {
case NPVariantType_Bool:
type = TYPE_BOOL;
break;
case NPVariantType_Int32:
type = TYPE_INT;
break;
case NPVariantType_Double:
type = TYPE_DOUBLE;
break;
case NPVariantType_String:
type = TYPE_STRING;
break;
case NPVariantType_Object:
{
// determine the most appropriate array type for the NPVariant object
NPVariantType nptype;
if(_NPN_ArrayObjectToVectorTypeHint(variant_.value.objectValue, nptype)) {
switch(nptype) {
case NPVariantType_Bool:
type = TYPE_BOOL_ARRAY;
break;
case NPVariantType_Int32:
type = TYPE_INT_ARRAY;
break;
case NPVariantType_Double:
type = TYPE_DOUBLE_ARRAY;
break;
case NPVariantType_String:
type = TYPE_STRING_ARRAY;
break;
}
}
}
break;
}
Unlock();
return type;
}
void CefVariantImpl::SetNull()
{
Lock();
NPN_ReleaseVariantValue(&variant_);
variant_.type = NPVariantType_Null;
Unlock();
}
void CefVariantImpl::SetBool(bool val)
{
Lock();
if(variant_.type != NPVariantType_Bool) {
SetNull();
variant_.type = NPVariantType_Bool;
}
variant_.value.boolValue = val;
Unlock();
}
void CefVariantImpl::SetInt(int val)
{
Lock();
if(variant_.type != NPVariantType_Int32) {
SetNull();
variant_.type = NPVariantType_Int32;
}
variant_.value.intValue = val;
Unlock();
}
void CefVariantImpl::SetDouble(double val)
{
Lock();
if(variant_.type != NPVariantType_Double) {
SetNull();
variant_.type = NPVariantType_Double;
}
variant_.value.doubleValue = val;
Unlock();
}
void CefVariantImpl::SetString(const std::wstring& val)
{
Lock();
SetNull();
variant_.type = NPVariantType_String;
std::string str = WideToUTF8(val);
NPString new_string = {str.c_str(),
static_cast<uint32_t>(str.size())};
_NPN_InitializeVariantWithStringCopy(&variant_, &new_string);
Unlock();
}
void CefVariantImpl::SetBoolArray(const std::vector<bool>& val)
{
Lock();
DCHECK(webframe_ != NULL);
WebCore::Frame* frame =
static_cast<WebCore::Frame*>(webframe_->GetFrameImplementation());
WebCore::DOMWindow* domwindow = frame->domWindow();
NPObject* npobject = _NPN_BooleanVectorToArrayObject(domwindow, val);
DCHECK(npobject != NULL);
Set(npobject);
Unlock();
}
void CefVariantImpl::SetIntArray(const std::vector<int>& val)
{
Lock();
DCHECK(webframe_ != NULL);
WebCore::Frame* frame =
static_cast<WebCore::Frame*>(webframe_->GetFrameImplementation());
WebCore::DOMWindow* domwindow = frame->domWindow();
NPObject* npobject = _NPN_IntVectorToArrayObject(domwindow, val);
DCHECK(npobject != NULL);
Set(npobject);
Unlock();
}
void CefVariantImpl::SetDoubleArray(const std::vector<double>& val)
{
Lock();
DCHECK(webframe_ != NULL);
WebCore::Frame* frame =
static_cast<WebCore::Frame*>(webframe_->GetFrameImplementation());
WebCore::DOMWindow* domwindow = frame->domWindow();
NPObject* npobject = _NPN_DoubleVectorToArrayObject(domwindow, val);
DCHECK(npobject != NULL);
Set(npobject);
Unlock();
}
void CefVariantImpl::SetStringArray(const std::vector<std::wstring>& val)
{
Lock();
DCHECK(webframe_ != NULL);
WebCore::Frame* frame =
static_cast<WebCore::Frame*>(webframe_->GetFrameImplementation());
WebCore::DOMWindow* domwindow = frame->domWindow();
NPObject* npobject = _NPN_WStringVectorToArrayObject(domwindow, val);
DCHECK(npobject != NULL);
Set(npobject);
Unlock();
}
bool CefVariantImpl::GetBool()
{
Lock();
DCHECK(variant_.type == NPVariantType_Bool);
bool rv = variant_.value.boolValue;
Unlock();
return rv;
}
int CefVariantImpl::GetInt()
{
Lock();
DCHECK(variant_.type == NPVariantType_Int32);
int rv = variant_.value.intValue;
Unlock();
return rv;
}
double CefVariantImpl::GetDouble()
{
Lock();
DCHECK(variant_.type == NPVariantType_Double);
double rv = variant_.value.doubleValue;
Unlock();
return rv;
}
std::wstring CefVariantImpl::GetString()
{
Lock();
DCHECK(variant_.type == NPVariantType_String);
std::wstring rv = UTF8ToWide(
std::string(
variant_.value.stringValue.UTF8Characters,
variant_.value.stringValue.UTF8Length));
Unlock();
return rv;
}
bool CefVariantImpl::GetBoolArray(std::vector<bool>& val)
{
Lock();
DCHECK(variant_.type == NPVariantType_Object);
bool rv = _NPN_ArrayObjectToBooleanVector(variant_.value.objectValue, val);
Unlock();
return rv;
}
bool CefVariantImpl::GetIntArray(std::vector<int>& val)
{
Lock();
DCHECK(variant_.type == NPVariantType_Object);
bool rv = _NPN_ArrayObjectToIntVector(variant_.value.objectValue, val);
Unlock();
return rv;
}
bool CefVariantImpl::GetDoubleArray(std::vector<double>& val)
{
Lock();
DCHECK(variant_.type == NPVariantType_Object);
bool rv = _NPN_ArrayObjectToDoubleVector(variant_.value.objectValue, val);
Unlock();
return rv;
}
bool CefVariantImpl::GetStringArray(std::vector<std::wstring>& val)
{
Lock();
DCHECK(variant_.type == NPVariantType_Object);
bool rv = _NPN_ArrayObjectToWStringVector(variant_.value.objectValue, val);
Unlock();
return rv;
}
void CefVariantImpl::CopyToNPVariant(NPVariant* result)
{
Lock();
result->type = variant_.type;
switch (variant_.type) {
case NPVariantType_Bool:
result->value.boolValue = variant_.value.boolValue;
break;
case NPVariantType_Int32:
result->value.intValue = variant_.value.intValue;
break;
case NPVariantType_Double:
result->value.doubleValue = variant_.value.doubleValue;
break;
case NPVariantType_String:
_NPN_InitializeVariantWithStringCopy(result, &variant_.value.stringValue);
break;
case NPVariantType_Null:
case NPVariantType_Void:
// Nothing to set.
break;
case NPVariantType_Object:
result->type = NPVariantType_Object;
result->value.objectValue = NPN_RetainObject(variant_.value.objectValue);
break;
}
Unlock();
}
void CefVariantImpl::Set(NPObject* val)
{
Lock();
SetNull();
variant_.type = NPVariantType_Object;
variant_.value.objectValue = NPN_RetainObject(val);
Unlock();
}
void CefVariantImpl::Set(const NPString& val)
{
Lock();
SetNull();
variant_.type = NPVariantType_String;
_NPN_InitializeVariantWithStringCopy(&variant_, &val);
Unlock();
}
void CefVariantImpl::Set(const NPVariant& val)
{
Lock();
SetNull();
switch (val.type) {
case NPVariantType_Bool:
SetBool(val.value.boolValue);
break;
case NPVariantType_Int32:
SetInt(val.value.intValue);
break;
case NPVariantType_Double:
SetDouble(val.value.doubleValue);
break;
case NPVariantType_String:
Set(val.value.stringValue);
break;
case NPVariantType_Object:
Set(val.value.objectValue);
break;
}
Unlock();
}

76
libcef/variant_impl.h Normal file
View File

@ -0,0 +1,76 @@
// Copyright (c) 2008 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.
#ifndef _VARIANT_IMPL_H
#define _VARIANT_IMPL_H
#include "../include/cef.h"
#include "third_party/npapi/bindings/npruntime.h"
class WebFrame;
// Implementation of CefPostDataElement that provides a class wrapper for an
// NPVariant structure.
// Portions of the implementation are borrowed from webkit\glue\cpp_variant.cc
class CefVariantImpl : public CefThreadSafeBase<CefVariant>
{
public:
CefVariantImpl();
CefVariantImpl(WebFrame *webframe);
~CefVariantImpl();
virtual Type GetType();
virtual void SetNull();
virtual void SetBool(bool val);
virtual void SetInt(int val);
virtual void SetDouble(double val);
virtual void SetString(const std::wstring& val);
virtual void SetBoolArray(const std::vector<bool>& val);
virtual void SetIntArray(const std::vector<int>& val);
virtual void SetDoubleArray(const std::vector<double>& val);
virtual void SetStringArray(const std::vector<std::wstring>& val);
virtual bool GetBool();
virtual int GetInt();
virtual double GetDouble();
virtual std::wstring GetString();
virtual bool GetBoolArray(std::vector<bool>& val);
virtual bool GetIntArray(std::vector<int>& val);
virtual bool GetDoubleArray(std::vector<double>& val);
virtual bool GetStringArray(std::vector<std::wstring>& val);
// These three methods all perform deep copies of any string data. This
// allows the local CefVariantImpl to be released by the destructor without
// corrupting their sources. In performance-critical code, or when strings
// are very long, avoid creating new CefVariantImpl.
// In case of NPObject as the data, the copying involves ref-counting
// as opposed to deep-copying. The ref-counting ensures that sources don't
// get corrupted when the copies get destroyed.
void CopyToNPVariant(NPVariant* result);
CefVariantImpl& operator=(const CefVariantImpl& original);
CefVariantImpl(const CefVariantImpl& original);
// Note that setting a CefVariant to an NPObject involves ref-counting
// the actual object. SetNull() should only be called if the CefVariant
// is no longer needed. The other Set() methods handle this internally.
// Also, the object's NPClass is expected to be a static object: neither
// the NP runtime nor CefVariant will ever free it.
void Set(NPObject* val);
void Set(const NPString& val);
void Set(const NPVariant& val);
const NPVariant* GetNPVariant() const { return &variant_; }
protected:
// Underlying NPVariant structure.
NPVariant variant_;
// Pointer to the WebFrame that represents the context for this CefVariant
// object. This pointer is used for creating new NPObjects in the Set*()
// methods that accept array arguments.
WebFrame* webframe_;
};
#endif // _VARIANT_IMPL_H

214
libcef/variant_np_util.cc Normal file
View File

@ -0,0 +1,214 @@
// Copyright (c) 2008 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 "precompiled_libcef.h"
#include "variant_np_util.h"
#include "config.h"
#include <v8.h>
#include "np_v8object.h"
#include "v8_proxy.h"
#undef LOG
#include "base/string_util.h"
#include "bindings/npruntime.h"
// NPScriptObjectClass defined in webkit\port\bindings\v8\np_v8object.cpp
extern NPClass* NPScriptObjectClass;
NPObject* _NPN_StringVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<std::string>& vec) {
v8::Local<v8::Array> array = v8::Array::New();
for (uint32_t index = 0; index < vec.size(); ++index) {
array->Set(v8::Integer::New(index),
v8::String::New(vec[index].c_str(), vec[index].length()));
}
return NPN_CreateScriptObject(0, array, domwindow);
}
NPObject* _NPN_WStringVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<std::wstring>& vec) {
v8::Local<v8::Array> array = v8::Array::New();
for (uint32_t index = 0; index < vec.size(); ++index) {
std::string str = WideToUTF8(vec[index].c_str());
array->Set(v8::Integer::New(index),
v8::String::New(str.c_str(), str.length()));
}
return NPN_CreateScriptObject(0, array, domwindow);
}
NPObject* _NPN_IntVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<int>& vec) {
v8::Local<v8::Array> array = v8::Array::New();
for (uint32_t index = 0; index < vec.size(); ++index) {
array->Set(v8::Integer::New(index), v8::Int32::New(vec[index]));
}
return NPN_CreateScriptObject(0, array, domwindow);
}
NPObject* _NPN_DoubleVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<double>& vec) {
v8::Local<v8::Array> array = v8::Array::New();
for (uint32_t index = 0; index < vec.size(); ++index) {
array->Set(v8::Integer::New(index), v8::Number::New(vec[index]));
}
return NPN_CreateScriptObject(0, array, domwindow);
}
NPObject* _NPN_BooleanVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<bool>& vec) {
v8::Local<v8::Array> array = v8::Array::New();
for (uint32_t index = 0; index < vec.size(); ++index) {
array->Set(v8::Integer::New(index), v8::Boolean::New(vec[index]));
}
return NPN_CreateScriptObject(0, array, domwindow);
}
bool _NPN_ArrayObjectToStringVector(NPObject* npobject,
std::vector<std::string>& vec) {
if (npobject == NULL || npobject->_class != NPScriptObjectClass)
return false;
V8NPObject *object = reinterpret_cast<V8NPObject*>(npobject);
if (!object->v8_object->IsArray())
return false;
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(object->v8_object);
for (uint32_t i = 0; i < array->Length(); i++) {
v8::Local<v8::Value> value = array->Get(v8::Integer::New(i));
v8::Local<v8::String> sval = value->ToString();
uint16_t* buf = new uint16_t[sval->Length()+1];
sval->Write(buf);
std::string utf8 = WideToUTF8(reinterpret_cast<wchar_t*>(buf));
vec.push_back(utf8);
delete[] buf;
}
return true;
}
bool _NPN_ArrayObjectToWStringVector(NPObject* npobject,
std::vector<std::wstring>& vec) {
if (npobject == NULL || npobject->_class != NPScriptObjectClass)
return false;
V8NPObject *object = reinterpret_cast<V8NPObject*>(npobject);
if (!object->v8_object->IsArray())
return false;
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(object->v8_object);
for (uint32_t i = 0; i < array->Length(); i++) {
v8::Local<v8::Value> value = array->Get(v8::Integer::New(i));
v8::Local<v8::String> sval = value->ToString();
uint16_t* buf = new uint16_t[sval->Length()+1];
sval->Write(buf);
std::wstring utf16 = reinterpret_cast<wchar_t*>(buf);
vec.push_back(utf16);
delete[] buf;
}
return true;
}
bool _NPN_ArrayObjectToIntVector(NPObject* npobject,
std::vector<int>& vec) {
if (npobject == NULL || npobject->_class != NPScriptObjectClass)
return false;
V8NPObject *object = reinterpret_cast<V8NPObject*>(npobject);
if (!object->v8_object->IsArray())
return false;
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(object->v8_object);
for (uint32_t i = 0; i < array->Length(); i++) {
v8::Local<v8::Value> value = array->Get(v8::Integer::New(i));
v8::Local<v8::Int32> ival = value->ToInt32();
vec.push_back(ival->Value());
}
return true;
}
bool _NPN_ArrayObjectToDoubleVector(NPObject* npobject,
std::vector<double>& vec) {
if (npobject == NULL || npobject->_class != NPScriptObjectClass)
return false;
V8NPObject *object = reinterpret_cast<V8NPObject*>(npobject);
if (!object->v8_object->IsArray())
return false;
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(object->v8_object);
for (uint32_t i = 0; i < array->Length(); i++) {
v8::Local<v8::Value> value = array->Get(v8::Integer::New(i));
v8::Local<v8::Number> dval = value->ToNumber();
vec.push_back(dval->Value());
}
return true;
}
bool _NPN_ArrayObjectToBooleanVector(NPObject* npobject,
std::vector<bool>& vec) {
if (npobject == NULL || npobject->_class != NPScriptObjectClass)
return false;
V8NPObject *object = reinterpret_cast<V8NPObject*>(npobject);
if (!object->v8_object->IsArray())
return false;
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(object->v8_object);
for (uint32_t i = 0; i < array->Length(); i++) {
v8::Local<v8::Value> value = array->Get(v8::Integer::New(i));
v8::Local<v8::Boolean> bval = value->ToBoolean();
vec.push_back(bval->Value());
}
return true;
}
bool _NPN_ArrayObjectToVectorTypeHint(NPObject* npobject,
NPVariantType &typehint)
{
if (npobject == NULL || npobject->_class != NPScriptObjectClass)
return false;
V8NPObject *object = reinterpret_cast<V8NPObject*>(npobject);
if (!object->v8_object->IsArray())
return false;
v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(object->v8_object);
if (array->Length() == 0)
return false;
typehint = NPVariantType_Null;
for (uint32_t i = 0; i < array->Length(); i++) {
v8::Local<v8::Value> value = array->Get(v8::Integer::New(i));
if (value->IsBoolean() && typehint <= NPVariantType_Bool) {
if (typehint != NPVariantType_Bool)
typehint = NPVariantType_Bool;
} else if (value->IsInt32() && typehint <= NPVariantType_Int32) {
if (typehint != NPVariantType_Int32)
typehint = NPVariantType_Int32;
} else if (value->IsNumber() && typehint <= NPVariantType_Double) {
if (typehint != NPVariantType_Double)
typehint = NPVariantType_Double;
} else {
typehint = NPVariantType_String;
// String is the least restrictive type, so we don't need to keep looking
break;
}
}
return true;
}

65
libcef/variant_np_util.h Normal file
View File

@ -0,0 +1,65 @@
// Copyright (c) 2008 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.
#ifndef _VARIANT_NP_UTIL_H
#define _VARIANT_NP_UTIL_H
#include "third_party/npapi/bindings/npruntime.h"
#include <string>
#include <vector>
#ifdef __cplusplus
extern "C" {
#endif
namespace WebCore {
class DOMWindow;
}
// Convert a vector of values to an NPObject, attached to the specified
// DOM Window, that represents a JavaScript Array of the same values.
NPObject* _NPN_StringVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<std::string>& vec);
NPObject* _NPN_WStringVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<std::wstring>& vec);
NPObject* _NPN_IntVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<int>& vec);
NPObject* _NPN_DoubleVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<double>& vec);
NPObject* _NPN_BooleanVectorToArrayObject(WebCore::DOMWindow* domwindow,
const std::vector<bool>& vec);
// Convert an NPObject that represents a JavaScript Array to a vector of
// values.
bool _NPN_ArrayObjectToStringVector(NPObject* npobject,
std::vector<std::string>& vec);
bool _NPN_ArrayObjectToWStringVector(NPObject* npobject,
std::vector<std::wstring>& vec);
bool _NPN_ArrayObjectToIntVector(NPObject* npobject,
std::vector<int>& vec);
bool _NPN_ArrayObjectToDoubleVector(NPObject* npobject,
std::vector<double>& vec);
bool _NPN_ArrayObjectToBooleanVector(NPObject* npobject,
std::vector<bool>& vec);
// Evaluate the types of values contained in an NPObject representing a
// JavaScript Array and suggest the most restrictive type that can safely store
// all of the Array values. For instance, if the Array contains all Int32
// values, the suggested type will be NPVariantType_Int32. If, on the other
// hand, the Array contains a mix of Int32 values and String values, then the
// suggested type will be NPVariantType_String. The supported values, from
// most restrictive to least restrictive, are NPVariantType_Bool,
// NPVariantType_Int32, NPVariantType_Double and NPVariantType_String. Arrays
// that contain values of type NPVariantType_Void, NPVariantType_Null or
// NPVariantType_Object will always result in a suggestion of type
// NPVariantType_String.
bool _NPN_ArrayObjectToVectorTypeHint(NPObject* npobject,
NPVariantType &typehint);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif // _VARIANT_NP_UTIL_H

50
libcef/webview_host.cc Normal file
View File

@ -0,0 +1,50 @@
// 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 "precompiled_libcef.h"
#include "webview_host.h"
#include "base/gfx/platform_canvas.h"
#include "base/gfx/rect.h"
#include "base/gfx/size.h"
#include "base/win_util.h"
#include "webkit/glue/webinputevent.h"
#include "webkit/glue/webview.h"
static const wchar_t kWindowClassName[] = L"WebViewHost";
/*static*/
WebViewHost* WebViewHost::Create(gfx::WindowHandle parent_window,
WebViewDelegate* delegate,
const WebPreferences& prefs) {
WebViewHost* host = new WebViewHost();
static bool registered_class = false;
if (!registered_class) {
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(wcex);
wcex.style = CS_DBLCLKS;
wcex.lpfnWndProc = WebWidgetHost::WndProc;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = kWindowClassName;
RegisterClassEx(&wcex);
registered_class = true;
}
host->view_ = CreateWindow(kWindowClassName, NULL,
WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, 0, 0,
0, 0, parent_window, NULL,
GetModuleHandle(NULL), NULL);
win_util::SetWindowUserData(host->view_, host);
host->webwidget_ = WebView::Create(delegate, prefs);
return host;
}
WebView* WebViewHost::webview() const {
return static_cast<WebView*>(webwidget_);
}

38
libcef/webview_host.h Normal file
View File

@ -0,0 +1,38 @@
// 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.
#ifndef _WEBVIEW_HOST_H
#define _WEBVIEW_HOST_H
#include "base/basictypes.h"
#include "base/gfx/native_widget_types.h"
#include "base/gfx/rect.h"
#include "base/scoped_ptr.h"
#include "webwidget_host.h"
struct WebPreferences;
class WebView;
class WebViewDelegate;
// This class is a simple ViewHandle-based host for a WebView
class WebViewHost : public WebWidgetHost {
public:
// The new instance is deleted once the associated ViewHandle is destroyed.
// The newly created window should be resized after it is created, using the
// MoveWindow (or equivalent) function.
static WebViewHost* Create(gfx::WindowHandle parent_window,
WebViewDelegate* delegate,
const WebPreferences& prefs);
WebView* webview() const;
protected:
#if defined(OS_WIN)
virtual bool WndProc(UINT message, WPARAM wparam, LPARAM lparam) {
return false;
}
#endif
};
#endif // _WEBVIEW_HOST_H

340
libcef/webwidget_host.cc Normal file
View File

@ -0,0 +1,340 @@
// 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 "precompiled_libcef.h"
#include "webwidget_host.h"
#include "base/gfx/platform_canvas.h"
#include "base/gfx/rect.h"
#include "base/logging.h"
#include "base/win_util.h"
#include "webkit/glue/webinputevent.h"
#include "webkit/glue/webwidget.h"
static const wchar_t kWindowClassName[] = L"WebWidgetHost";
/*static*/
WebWidgetHost* WebWidgetHost::Create(gfx::WindowHandle parent_window,
WebWidgetDelegate* delegate) {
WebWidgetHost* host = new WebWidgetHost();
static bool registered_class = false;
if (!registered_class) {
WNDCLASSEX wcex = {0};
wcex.cbSize = sizeof(wcex);
wcex.style = CS_DBLCLKS;
wcex.lpfnWndProc = WebWidgetHost::WndProc;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = kWindowClassName;
RegisterClassEx(&wcex);
registered_class = true;
}
host->view_ = CreateWindowEx(WS_EX_TOOLWINDOW,
kWindowClassName, kWindowClassName, WS_POPUP,
0, 0, 0, 0,
parent_window, NULL, GetModuleHandle(NULL), NULL);
win_util::SetWindowUserData(host->view_, host);
host->webwidget_ = WebWidget::Create(delegate);
return host;
}
/*static*/
WebWidgetHost* WebWidgetHost::FromWindow(gfx::WindowHandle hwnd) {
return reinterpret_cast<WebWidgetHost*>(win_util::GetWindowUserData(hwnd));
}
/*static*/
LRESULT CALLBACK WebWidgetHost::WndProc(HWND hwnd, UINT message, WPARAM wparam,
LPARAM lparam) {
WebWidgetHost* host = FromWindow(hwnd);
if (host && !host->WndProc(message, wparam, lparam)) {
switch (message) {
case WM_DESTROY:
delete host;
break;
case WM_PAINT: {
RECT rect;
if (GetUpdateRect(hwnd, &rect, FALSE)) {
host->UpdatePaintRect(gfx::Rect(rect));
}
host->Paint();
return 0;
}
case WM_ERASEBKGND:
// Do nothing here to avoid flashing, the background will be erased
// during painting.
return 0;
case WM_SIZE:
host->Resize(lparam);
return 0;
case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
host->MouseEvent(message, wparam, lparam);
break;
case WM_MOUSEWHEEL:
host->WheelEvent(wparam, lparam);
break;
case WM_CAPTURECHANGED:
case WM_CANCELMODE:
host->CaptureLostEvent();
break;
// TODO(darin): add WM_SYSKEY{DOWN/UP} to capture ALT key actions
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_CHAR:
case WM_SYSCHAR:
case WM_IME_CHAR:
host->KeyEvent(message, wparam, lparam);
break;
case WM_SETFOCUS:
host->SetFocus(true);
break;
case WM_KILLFOCUS:
host->SetFocus(false);
break;
}
}
return DefWindowProc(hwnd, message, wparam, lparam);;
}
void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
DLOG_IF(WARNING, painting_) << "unexpected invalidation while painting";
// If this invalidate overlaps with a pending scroll, then we have to
// downgrade to invalidating the scroll rect.
if (damaged_rect.Intersects(scroll_rect_)) {
paint_rect_ = paint_rect_.Union(scroll_rect_);
ResetScrollRect();
}
paint_rect_ = paint_rect_.Union(damaged_rect);
RECT r = damaged_rect.ToRECT();
InvalidateRect(view_, &r, FALSE);
}
void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
DCHECK(dx || dy);
// If we already have a pending scroll operation or if this scroll operation
// intersects the existing paint region, then just failover to invalidating.
if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) {
paint_rect_ = paint_rect_.Union(scroll_rect_);
ResetScrollRect();
paint_rect_ = paint_rect_.Union(clip_rect);
}
// We will perform scrolling lazily, when requested to actually paint.
scroll_rect_ = clip_rect;
scroll_dx_ = dx;
scroll_dy_ = dy;
RECT r = clip_rect.ToRECT();
InvalidateRect(view_, &r, FALSE);
}
void WebWidgetHost::SetCursor(HCURSOR cursor) {
SetClassLong(view_, GCL_HCURSOR,
static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
::SetCursor(cursor);
}
void WebWidgetHost::DiscardBackingStore() {
canvas_.reset();
}
WebWidgetHost::WebWidgetHost()
: view_(NULL),
webwidget_(NULL),
track_mouse_leave_(false),
scroll_dx_(0),
scroll_dy_(0) {
set_painting(false);
}
WebWidgetHost::~WebWidgetHost() {
win_util::SetWindowUserData(view_, 0);
TrackMouseLeave(false);
webwidget_->Close();
webwidget_->Release();
}
bool WebWidgetHost::WndProc(UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_ACTIVATE:
if (wparam == WA_INACTIVE) {
PostMessage(view_, WM_CLOSE, 0, 0);
return true;
}
break;
}
return false;
}
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
paint_rect_ = paint_rect_.Union(rect);
}
void WebWidgetHost::Paint() {
RECT r;
GetClientRect(view_, &r);
gfx::Rect client_rect(r);
// Allocate a canvas if necessary
if (!canvas_.get()) {
ResetScrollRect();
paint_rect_ = client_rect;
canvas_.reset(new gfx::PlatformCanvas(
paint_rect_.width(), paint_rect_.height(), true));
}
// This may result in more invalidation
webwidget_->Layout();
// Scroll the canvas if necessary
scroll_rect_ = client_rect.Intersect(scroll_rect_);
if (!scroll_rect_.IsEmpty()) {
HDC hdc = canvas_->getTopPlatformDevice().getBitmapDC();
RECT damaged_rect, r = scroll_rect_.ToRECT();
ScrollDC(hdc, scroll_dx_, scroll_dy_, NULL, &r, NULL, &damaged_rect);
PaintRect(gfx::Rect(damaged_rect));
}
ResetScrollRect();
// Paint the canvas if necessary. Allow painting to generate extra rects the
// first time we call it. This is necessary because some WebCore rendering
// objects update their layout only when painted.
for (int i = 0; i < 2; ++i) {
paint_rect_ = client_rect.Intersect(paint_rect_);
if (!paint_rect_.IsEmpty()) {
gfx::Rect rect(paint_rect_);
paint_rect_ = gfx::Rect();
DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations";
PaintRect(rect);
}
}
DCHECK(paint_rect_.IsEmpty());
// Paint to the screen
PAINTSTRUCT ps;
BeginPaint(view_, &ps);
canvas_->getTopPlatformDevice().drawToHDC(ps.hdc,
ps.rcPaint.left,
ps.rcPaint.top,
&ps.rcPaint);
EndPaint(view_, &ps);
// Draw children
UpdateWindow(view_);
}
void WebWidgetHost::Resize(LPARAM lparam) {
// Force an entire re-paint. TODO(darin): Maybe reuse this memory buffer.
DiscardBackingStore();
webwidget_->Resize(gfx::Size(LOWORD(lparam), HIWORD(lparam)));
}
void WebWidgetHost::MouseEvent(UINT message, WPARAM wparam, LPARAM lparam) {
WebMouseEvent event(view_, message, wparam, lparam);
switch (event.type) {
case WebInputEvent::MOUSE_MOVE:
TrackMouseLeave(true);
break;
case WebInputEvent::MOUSE_LEAVE:
TrackMouseLeave(false);
break;
case WebInputEvent::MOUSE_DOWN:
SetCapture(view_);
break;
case WebInputEvent::MOUSE_UP:
if (GetCapture() == view_)
ReleaseCapture();
break;
}
webwidget_->HandleInputEvent(&event);
}
void WebWidgetHost::WheelEvent(WPARAM wparam, LPARAM lparam) {
WebMouseWheelEvent event(view_, WM_MOUSEWHEEL, wparam, lparam);
webwidget_->HandleInputEvent(&event);
}
void WebWidgetHost::KeyEvent(UINT message, WPARAM wparam, LPARAM lparam) {
WebKeyboardEvent event(view_, message, wparam, lparam);
webwidget_->HandleInputEvent(&event);
}
void WebWidgetHost::CaptureLostEvent() {
webwidget_->MouseCaptureLost();
}
void WebWidgetHost::SetFocus(bool enable) {
webwidget_->SetFocus(enable);
}
void WebWidgetHost::TrackMouseLeave(bool track) {
if (track == track_mouse_leave_)
return;
track_mouse_leave_ = track;
DCHECK(view_);
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
if (!track_mouse_leave_)
tme.dwFlags |= TME_CANCEL;
tme.hwndTrack = view_;
TrackMouseEvent(&tme);
}
void WebWidgetHost::ResetScrollRect() {
scroll_rect_ = gfx::Rect();
scroll_dx_ = 0;
scroll_dy_ = 0;
}
void WebWidgetHost::PaintRect(const gfx::Rect& rect) {
#ifndef NDEBUG
DCHECK(!painting_);
#endif
DCHECK(canvas_.get());
set_painting(true);
webwidget_->Paint(canvas_.get(), rect);
set_painting(false);
}

120
libcef/webwidget_host.h Normal file
View File

@ -0,0 +1,120 @@
// 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.
#ifndef _WEBWIDGET_HOST_H
#define _WEBWIDGET_HOST_H
#include "base/basictypes.h"
#include "base/gfx/native_widget_types.h"
#include "base/gfx/platform_canvas.h"
#include "base/gfx/rect.h"
#include "base/scoped_ptr.h"
class WebWidget;
class WebWidgetDelegate;
namespace gfx {
class Size;
}
// This class is a simple ViewHandle-based host for a WebWidget
class WebWidgetHost {
public:
// The new instance is deleted once the associated ViewHandle is destroyed.
// The newly created window should be resized after it is created, using the
// MoveWindow (or equivalent) function.
static WebWidgetHost* Create(gfx::WindowHandle parent_window,
WebWidgetDelegate* delegate);
static WebWidgetHost* FromWindow(gfx::WindowHandle view);
#if defined(OS_MACOSX)
static void HandleEvent(gfx::WindowHandle window, NSEvent *event);
#endif
gfx::ViewHandle window_handle() const { return view_; }
WebWidget* webwidget() const { return webwidget_; }
void DidInvalidateRect(const gfx::Rect& rect);
void DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect);
#if defined(OS_WIN)
void SetCursor(HCURSOR cursor);
#endif
void DiscardBackingStore();
// Allow clients to update the paint rect. For example, if we get a gdk
// expose or WM_PAINT event, we need to update the paint rect.
void UpdatePaintRect(const gfx::Rect& rect);
void Paint();
protected:
WebWidgetHost();
~WebWidgetHost();
#if defined(OS_WIN)
// Per-class wndproc. Returns true if the event should be swallowed.
virtual bool WndProc(UINT message, WPARAM wparam, LPARAM lparam);
void Resize(LPARAM lparam);
void MouseEvent(UINT message, WPARAM wparam, LPARAM lparam);
void WheelEvent(WPARAM wparam, LPARAM lparam);
void KeyEvent(UINT message, WPARAM wparam, LPARAM lparam);
void CaptureLostEvent();
void SetFocus(bool enable);
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
#elif defined(OS_MACOSX)
// These need to be called from a non-subclass, so they need to be public.
public:
void Resize(const gfx::Rect& rect);
void MouseEvent(NSEvent *);
void WheelEvent(NSEvent *);
void KeyEvent(NSEvent *);
void SetFocus(bool enable);
protected:
#elif defined(OS_LINUX)
public:
// ---------------------------------------------------------------------------
// This is needed on Linux because the GtkWidget creation is the same between
// both web view hosts and web widget hosts. The Windows code manages this by
// reusing the WndProc function (static, above). However, GTK doesn't use a
// single big callback function like that so we have a static function that
// sets up a GtkWidget correctly.
// parent: a GtkBox to pack the new widget at the end of
// host: a pointer to a WebWidgetHost (or subclass thereof)
// ---------------------------------------------------------------------------
static gfx::WindowHandle CreateWindow(gfx::WindowHandle parent, void* host);
void WindowDestroyed();
void Resize(const gfx::Size& size);
#endif
void TrackMouseLeave(bool enable);
void ResetScrollRect();
void PaintRect(const gfx::Rect& rect);
void set_painting(bool value) {
#ifndef NDEBUG
painting_ = value;
#endif
}
gfx::ViewHandle view_;
WebWidget* webwidget_;
scoped_ptr<gfx::PlatformCanvas> canvas_;
// specifies the portion of the webwidget that needs painting
gfx::Rect paint_rect_;
// specifies the portion of the webwidget that needs scrolling
gfx::Rect scroll_rect_;
int scroll_dx_;
int scroll_dy_;
bool track_mouse_leave_;
#ifndef NDEBUG
bool painting_;
#endif
};
#endif // _WEBWIDGET_HOST_H

View File

@ -0,0 +1,860 @@
// Copyright (c) 2008 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 "cefclient.h"
#include "cef.h"
#include <sstream>
#define MAX_LOADSTRING 100
#define MAX_URL_LENGTH 255
#define BUTTON_WIDTH 72
#define URLBAR_HEIGHT 24
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// Initialize the CEF
CefInitialize();
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_CEFCLIENT, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CEFCLIENT));
// Main message loop
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Shut down the CEF
CefShutdown();
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this
// function so that the application will get 'well formed' small icons
// associated with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CEFCLIENT));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CEFCLIENT);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, 0, CW_USEDEFAULT,
0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// Client implementation of the JS handler class
// Select the "JavaScript" option from the "Tests" menu for an example
class ClientJSHandler : public CefThreadSafeBase<CefJSHandler>
{
public:
ClientJSHandler()
{
}
~ClientJSHandler()
{
}
// Return true if the specified method exists.
virtual bool HasMethod(CefRefPtr<CefBrowser> browser,
const std::wstring& name)
{
// We have a method called "mymethod"
return (name.compare(L"mymethod") == 0);
}
// Return true if the specified property exists.
virtual bool HasProperty(CefRefPtr<CefBrowser> browser,
const std::wstring& name)
{
return false;
}
// Set the property value. Return true if the property is accepted.
virtual bool SetProperty(CefRefPtr<CefBrowser> browser,
const std::wstring& name,
const CefRefPtr<CefVariant> value)
{
return false;
}
// Get the property value. Return true if the value is returned.
virtual bool GetProperty(CefRefPtr<CefBrowser> browser,
const std::wstring& name,
CefRefPtr<CefVariant> value)
{
return false;
}
// Execute a method with the specified argument vector and return
// value. Return true if the method was handled.
virtual bool ExecuteMethod(CefRefPtr<CefBrowser> browser,
const std::wstring& name,
const VariantVector& args,
CefRefPtr<CefVariant> retval)
{
// We only handle the "mymethod" method
if(name.compare(L"mymethod") != 0)
return false;
// Return a description of the input arguments
std::wstringstream ss;
for(size_t i = 0; i < args.size(); i++)
{
ss << L"arg" << i;
switch(args[i]->GetType())
{
case CefVariant::TYPE_NULL:
ss << L" null";
break;
case CefVariant::TYPE_BOOL:
ss << L" bool = " << args[i]->GetBool();
break;
case CefVariant::TYPE_INT:
ss << L" int = " << args[i]->GetInt();
break;
case CefVariant::TYPE_DOUBLE:
ss << L" double = " << args[i]->GetDouble();
break;
case CefVariant::TYPE_STRING:
ss << L" string = " << args[i]->GetString().c_str();
break;
case CefVariant::TYPE_BOOL_ARRAY:
ss << L" bool array = ";
{
std::vector<bool> vec;
args[i]->GetBoolArray(vec);
for(size_t x = 0; x < vec.size(); x++)
{
ss << vec[x];
if(x < vec.size()-1)
ss << L",";
}
}
break;
case CefVariant::TYPE_INT_ARRAY:
ss << L" int array = ";
{
std::vector<int> vec;
args[i]->GetIntArray(vec);
for(size_t x = 0; x < vec.size(); x++)
{
ss << vec[x];
if(x < vec.size()-1)
ss << L",";
}
}
break;
case CefVariant::TYPE_DOUBLE_ARRAY:
ss << L" double array = ";
{
std::vector<double> vec;
args[i]->GetDoubleArray(vec);
for(size_t x = 0; x < vec.size(); x++)
{
ss << vec[x];
if(x < vec.size()-1)
ss << L",";
}
}
break;
case CefVariant::TYPE_STRING_ARRAY:
ss << L" string array = ";
{
std::vector<std::wstring> vec;
args[i]->GetStringArray(vec);
for(size_t x = 0; x < vec.size(); x++)
{
ss << vec[x].c_str();
if(x < vec.size()-1)
ss << L",";
}
}
break;
}
ss << L"\n<br>";
}
retval->SetString(ss.str());
return true;
}
};
// Load a resource of type BINARY
bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes)
{
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(binaryId),
MAKEINTRESOURCE(256));
if(hRes)
{
HGLOBAL hGlob = LoadResource(hInst, hRes);
if(hGlob)
{
dwSize = SizeofResource(hInst, hRes);
pBytes = (LPBYTE)LockResource(hGlob);
if(dwSize > 0 && pBytes)
return true;
}
}
return false;
}
// Client implementation of the browser handler class
class ClientHandler : public CefThreadSafeBase<CefHandler>
{
public:
ClientHandler()
{
m_MainHwnd = NULL;
m_BrowserHwnd = NULL;
m_EditHwnd = NULL;
m_bLoading = false;
m_bCanGoBack = false;
m_bCanGoForward = false;
}
~ClientHandler()
{
}
// Event called before a new window is created. The |parentBrowser| parameter
// will point to the parent browser window, if any. The |popup| parameter
// will be true if the new window is a popup window. If you create the window
// yourself you should populate the window handle member of |createInfo| and
// return RV_HANDLED. Otherwise, return RV_CONTINUE and the framework will
// create the window. By default, a newly created window will recieve the
// same handler as the parent window. To change the handler for the new
// window modify the object that |handler| points to.
virtual RetVal HandleBeforeCreated(CefRefPtr<CefBrowser> parentBrowser,
CefWindowInfo& createInfo, bool popup,
CefRefPtr<CefHandler>& handler,
std::wstring& url)
{
return RV_CONTINUE;
}
// Event called after a new window is created. The return value is currently
// ignored.
virtual RetVal HandleAfterCreated(CefRefPtr<CefBrowser> browser)
{
Lock();
if(!browser->IsPopup())
{
// We need to keep the main child window, but not popup windows
m_Browser = browser;
m_BrowserHwnd = browser->GetWindowHandle();
}
// Register our JavaScript "myclass" object
browser->AddJSHandler(L"myclass", new ClientJSHandler());
Unlock();
return RV_CONTINUE;
}
// Event called when the address bar changes. The return value is currently
// ignored.
virtual RetVal HandleAddressChange(CefRefPtr<CefBrowser> browser,
const std::wstring& url)
{
// Set the edit window text
SetWindowText(m_EditHwnd, url.c_str());
return RV_CONTINUE;
}
// Event called when the page title changes. The return value is currently
// ignored.
virtual RetVal HandleTitleChange(CefRefPtr<CefBrowser> browser,
const std::wstring& title)
{
// Set the frame window title bar
SetWindowText(m_MainHwnd, title.c_str());
return RV_CONTINUE;
}
// Event called before browser navigation. The client has an opportunity to
// modify the |request| object if desired. Return RV_HANDLED to cancel
// navigation.
virtual RetVal HandleBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
NavType navType, bool isRedirect)
{
return RV_CONTINUE;
}
// Event called when the browser begins loading a page. The return value is
// currently ignored.
virtual RetVal HandleLoadStart(CefRefPtr<CefBrowser> browser)
{
Lock();
// We've just started loading a page
m_bLoading = true;
m_bCanGoBack = false;
m_bCanGoForward = false;
Unlock();
return RV_CONTINUE;
}
// Event called when the browser is done loading a page. This event will
// be generated irrespective of whether the request completes successfully.
// The return value is currently ignored.
virtual RetVal HandleLoadEnd(CefRefPtr<CefBrowser> browser)
{
Lock();
// We've just finished loading a page
m_bLoading = false;
m_bCanGoBack = browser->CanGoBack();
m_bCanGoForward = browser->CanGoForward();
Unlock();
return RV_CONTINUE;
}
// Called when the browser fails to load a resource. |errorCode is the
// error code number and |failedUrl| is the URL that failed to load. To
// provide custom error text assign the text to |errorText| and return
// RV_HANDLED. Otherwise, return RV_CONTINUE for the default error text.
virtual RetVal HandleLoadError(CefRefPtr<CefBrowser> browser,
ErrorCode errorCode,
const std::wstring& failedUrl,
std::wstring& errorText)
{
if(errorCode == ERR_CACHE_MISS)
{
// Usually caused by navigating to a page with POST data via back or
// forward buttons.
errorText = L"<html><head><title>Expired Form Data</title></head>"
L"<body><h1>Expired Form Data</h1>"
L"<h2>Your form request has expired. "
L"Click reload to re-submit the form data.</h2></body>"
L"</html>";
}
else
{
// All other messages.
std::wstringstream ss;
ss << L"<html><head><title>Load Failed</title></head>"
L"<body><h1>Load Failed</h1>"
L"<h2>Load of URL " << failedUrl <<
L"failed with error code " << static_cast<int>(errorCode) <<
L".</h2></body>"
L"</html>";
errorText = ss.str();
}
return RV_HANDLED;
}
// Event called before a resource is loaded. To allow the resource to load
// normally return RV_CONTINUE. To redirect the resource to a new url
// populate the |redirectUrl| value and return RV_CONTINUE. To specify
// data for the resource return a CefStream object in |resourceStream|, set
// 'mimeType| to the resource stream's mime type, and return RV_CONTINUE.
// To cancel loading of the resource return RV_HANDLED.
virtual RetVal HandleBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
std::wstring& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
std::wstring& mimeType,
int loadFlags)
{
std::wstring url = request->GetURL();
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::CreateForData(pBytes, dwSize);
mimeType = L"image/jpg";
}
}
return RV_CONTINUE;
}
// Event called before a context menu is displayed. To cancel display of the
// default context menu return RV_HANDLED.
virtual RetVal HandleBeforeMenu(CefRefPtr<CefBrowser> browser,
const MenuInfo& menuInfo)
{
return RV_CONTINUE;
}
// Event called to optionally override the default text for a context menu
// item. |label| contains the default text and may be modified to substitute
// alternate text. The return value is currently ignored.
virtual RetVal HandleGetMenuLabel(CefRefPtr<CefBrowser> browser,
MenuId menuId, std::wstring& label)
{
return RV_CONTINUE;
}
// Event called when an option is selected from the default context menu.
// Return RV_HANDLED to cancel default handling of the action.
virtual RetVal HandleMenuAction(CefRefPtr<CefBrowser> browser,
MenuId menuId)
{
return RV_CONTINUE;
}
// Event called to format print headers and footers. |printInfo| contains
// platform-specific information about the printer context. |url| is the
// URL if the currently printing page, |title| is the title of the currently
// printing page, |currentPage| is the current page number and |maxPages| is
// the total number of pages. Six default header locations are provided
// by the implementation: top left, top center, top right, bottom left,
// bottom center and bottom right. To use one of these default locations
// just assign a string to the appropriate variable. To draw the header
// and footer yourself return RV_HANDLED. Otherwise, populate the approprate
// variables and return RV_CONTINUE.
virtual RetVal HandlePrintHeaderFooter(CefRefPtr<CefBrowser> browser,
CefPrintInfo& printInfo,
const std::wstring& url,
const std::wstring& title,
int currentPage, int maxPages,
std::wstring& topLeft,
std::wstring& topCenter,
std::wstring& topRight,
std::wstring& bottomLeft,
std::wstring& bottomCenter,
std::wstring& bottomRight)
{
// Place the page title at top left
topLeft = title;
// Place the page URL at top right
topRight = url;
// Place "Page X of Y" at bottom center
std::wstringstream strstream;
strstream << L"Page " << currentPage << L" of " << maxPages;
bottomCenter = strstream.str();
return RV_CONTINUE;
}
// Run a JS alert message. Return RV_CONTINUE to display the default alert
// or RV_HANDLED if you displayed a custom alert.
virtual RetVal HandleJSAlert(CefRefPtr<CefBrowser> browser,
const std::wstring& message)
{
return RV_CONTINUE;
}
// Run a JS confirm request. Return RV_CONTINUE to display the default alert
// or RV_HANDLED if you displayed a custom alert. If you handled the alert
// set |retval| to true if the user accepted the confirmation.
virtual RetVal HandleJSConfirm(CefRefPtr<CefBrowser> browser,
const std::wstring& message, bool& retval)
{
return RV_CONTINUE;
}
// Run a JS prompt request. Return RV_CONTINUE to display the default prompt
// or RV_HANDLED if you displayed a custom prompt. If you handled the prompt
// set |retval| to true if the user accepted the prompt and request and
// |result| to the resulting value.
virtual RetVal HandleJSPrompt(CefRefPtr<CefBrowser> browser,
const std::wstring& message,
const std::wstring& default_value,
bool& retval,
std::wstring& result)
{
return RV_CONTINUE;
}
// Retrieve the current navigation state flags
void GetNavState(bool &isLoading, bool &canGoBack, bool &canGoForward)
{
Lock();
isLoading = m_bLoading;
canGoBack = m_bCanGoBack;
canGoForward = m_bCanGoForward;
Unlock();
}
void SetMainHwnd(HWND hwnd)
{
Lock();
m_MainHwnd = hwnd;
Unlock();
}
void SetEditHwnd(HWND hwnd)
{
Lock();
m_EditHwnd = hwnd;
Unlock();
}
CefRefPtr<CefBrowser> GetBrowser()
{
return m_Browser;
}
HWND GetBrowserHwnd()
{
return m_BrowserHwnd;
}
protected:
// The child browser window
CefRefPtr<CefBrowser> m_Browser;
// The main frame window handle
HWND m_MainHwnd;
// The child browser window handle
HWND m_BrowserHwnd;
// The edit window handle
HWND m_EditHwnd;
// True if the page is currently loading
bool m_bLoading;
// True if the user can navigate backwards
bool m_bCanGoBack;
// True if the user can navigate forwards
bool m_bCanGoForward;
};
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
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;
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
if(hWnd == editWnd)
{
// Callback for the edit window
switch (message)
{
case WM_CHAR:
if (wParam == VK_RETURN && handler.get())
{
// When the user hits the enter key load the URL
CefRefPtr<CefBrowser> browser = handler->GetBrowser();
wchar_t strPtr[MAX_URL_LENGTH];
*((LPWORD)strPtr) = MAX_URL_LENGTH;
LRESULT strLen = SendMessage(hWnd, EM_GETLINE, 0, (LPARAM)strPtr);
if (strLen > 0)
browser->LoadURL(strPtr, std::wstring());
return 0;
}
}
return (LRESULT)CallWindowProc(editWndOldProc, hWnd, message, wParam, lParam);
}
else
{
// Callback for the main window
switch (message)
{
case WM_CREATE:
{
// Create the single static handler class instance
handler = new ClientHandler();
handler->SetMainHwnd(hWnd);
// Create the child windows used for navigation
RECT rect;
int x = 0;
GetClientRect(hWnd, &rect);
backWnd = CreateWindow(L"BUTTON", L"Back",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
| WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
hWnd, (HMENU) IDC_NAV_BACK, hInst, 0);
x += BUTTON_WIDTH;
forwardWnd = CreateWindow(L"BUTTON", L"Forward",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
| WS_DISABLED, x, 0, BUTTON_WIDTH,
URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_FORWARD,
hInst, 0);
x += BUTTON_WIDTH;
reloadWnd = CreateWindow(L"BUTTON", L"Reload",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
| WS_DISABLED, x, 0, BUTTON_WIDTH,
URLBAR_HEIGHT, hWnd, (HMENU) IDC_NAV_RELOAD,
hInst, 0);
x += BUTTON_WIDTH;
stopWnd = CreateWindow(L"BUTTON", L"Stop",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON
| WS_DISABLED, x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
hWnd, (HMENU) IDC_NAV_STOP, hInst, 0);
x += BUTTON_WIDTH;
editWnd = CreateWindow(L"EDIT", 0,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
ES_AUTOVSCROLL | ES_AUTOHSCROLL| WS_DISABLED,
x, 0, rect.right - BUTTON_WIDTH * 4,
URLBAR_HEIGHT, hWnd, 0, hInst, 0);
// Assign the edit window's WNDPROC to this function so that we can
// capture the enter key
editWndOldProc =
reinterpret_cast<WNDPROC>(GetWindowLongPtr(editWnd, GWLP_WNDPROC));
SetWindowLongPtr(editWnd, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(WndProc));
handler->SetEditHwnd(editWnd);
rect.top += URLBAR_HEIGHT;
CefWindowInfo info;
// Initialize window info to the defaults for a child window
info.SetAsChild(hWnd, rect);
// Creat the new child child browser window
CefBrowser::CreateBrowser(info, false,
static_cast<CefRefPtr<CefHandler>>(handler),
L"http://www.google.com");
// Start the timer that will be used to update child window state
SetTimer(hWnd, 1, 500, NULL);
}
return 0;
case WM_TIMER:
if(handler.get() && handler->GetBrowserHwnd())
{
// Retrieve the current navigation state
bool isLoading, canGoBack, canGoForward;
handler->GetNavState(isLoading, canGoBack, canGoForward);
// Update the status of child windows
EnableWindow(editWnd, TRUE);
EnableWindow(backWnd, canGoBack);
EnableWindow(forwardWnd, canGoForward);
EnableWindow(reloadWnd, !isLoading);
EnableWindow(stopWnd, isLoading);
}
case WM_COMMAND:
{
CefRefPtr<CefBrowser> browser;
if(handler.get())
browser = handler->GetBrowser();
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
return 0;
case IDM_EXIT:
DestroyWindow(hWnd);
return 0;
case IDC_NAV_BACK: // Back button
if(browser.get())
browser->GoBack();
return 0;
case IDC_NAV_FORWARD: // Forward button
if(browser.get())
browser->GoForward();
return 0;
case IDC_NAV_RELOAD: // Reload button
if(browser.get())
browser->Reload();
return 0;
case IDC_NAV_STOP: // Stop button
if(browser.get())
browser->StopLoad();
return 0;
case ID_TESTS_JAVASCRIPT: // Test our javascript handler
if(browser.get())
{
std::wstring html =
L"<html><body>ClientJSHandler says:<br>"
L"<script language=\"JavaScript\">"
L"document.writeln(window.myclass.mymethod('foo', 1, 7.6654, 'bar',"
L"[5, 6, 1, 8]));"
L"</script>"
L"</body></html>";
browser->LoadString(html, L"about:blank");
}
return 0;
}
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_SETFOCUS:
if(handler.get() && handler->GetBrowserHwnd())
{
// Pass focus to the browser window
PostMessage(handler->GetBrowserHwnd(), WM_SETFOCUS, wParam, NULL);
}
return 0;
case WM_SIZE:
if(handler.get() && handler->GetBrowserHwnd())
{
// Resize the browser window and address bar to match the new frame
// window size
RECT rect;
GetClientRect(hWnd, &rect);
rect.top += URLBAR_HEIGHT;
int urloffset = rect.left + BUTTON_WIDTH * 4;
HDWP hdwp = BeginDeferWindowPos(1);
hdwp = DeferWindowPos(hdwp, editWnd, NULL, urloffset,
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
hdwp = DeferWindowPos(hdwp, handler->GetBrowserHwnd(), NULL,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
SWP_NOZORDER);
EndDeferWindowPos(hdwp);
}
break;
case WM_ERASEBKGND:
if(handler.get() && handler->GetBrowserHwnd())
{
// Dont erase the background if the browser window has been loaded
// (this avoids flashing)
return 0;
}
break;
case WM_DESTROY:
// The frame window has exited
KillTimer(hWnd, 1);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}

View File

@ -0,0 +1,7 @@
// Copyright (c) 2008 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 "resource.h"

View File

@ -0,0 +1,147 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Binary
//
IDS_LOGO BINARY "res\logo.jpg"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_CEFCLIENT ICON "res\cefclient.ico"
IDI_SMALL ICON "res\small.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_CEFCLIENT MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
POPUP "Tests"
BEGIN
MENUITEM "JavaScript", ID_TESTS_JAVASCRIPT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDC_CEFCLIENT ACCELERATORS
BEGIN
"?", IDM_ABOUT, ASCII, ALT
"/", IDM_ABOUT, ASCII, ALT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG 22, 17, 230, 75
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 8, "System"
BEGIN
ICON IDI_CEFCLIENT,IDC_MYICON,14,9,16,16
LTEXT "cefclient Version 1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX
LTEXT "Copyright (C) 2008",IDC_STATIC,49,20,119,8
DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_APP_TITLE "cefclient"
IDC_CEFCLIENT "CEFCLIENT"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,215 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="cefclient"
ProjectGUID="{6617FED9-C5D4-4907-BF55-A90062A6683F}"
RootNamespace="cefclient"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
ConfigurationType="1"
InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\cefclient.vsprops"
UseOfMFC="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="stdafx.h"
WarnAsError="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
IgnoreDefaultLibraryNames=""
SubSystem="2"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
ConfigurationType="1"
InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\cefclient.vsprops"
UseOfMFC="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
RuntimeLibrary="0"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="stdafx.h"
WarnAsError="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
SubSystem="2"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="resources"
>
<File
RelativePath=".\cefclient.ico"
>
</File>
<File
RelativePath=".\res\logo.jpg"
>
</File>
<File
RelativePath=".\small.ico"
>
</File>
</Filter>
<File
RelativePath=".\cefclient.cpp"
>
</File>
<File
RelativePath=".\cefclient.h"
>
</File>
<File
RelativePath=".\cefclient.rc"
>
</File>
<File
RelativePath=".\Resource.h"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="cefclient"
InheritedPropertySheets="$(SolutionDir)libcef\libcef.vsprops;"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(SolutionDir)\include&quot;;&quot;$(OutDir)&quot;"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib shlwapi.lib rpcrt4.lib winmm.lib"
AdditionalLibraryDirectories="&quot;$(OutDir)&quot;"
/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(IntDir)\..\&quot;"
/>
</VisualStudioPropertySheet>

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,38 @@
// Copyright (c) 2008 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.
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by cefclient.rc
//
#define BINARY 256
#define IDC_MYICON 2
#define IDD_CEFCLIENT_DIALOG 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDI_CEFCLIENT 107
#define IDI_SMALL 108
#define IDC_CEFCLIENT 109
#define IDR_MAINFRAME 128
#define IDC_NAV_BACK 200
#define IDC_NAV_FORWARD 201
#define IDC_NAV_RELOAD 202
#define IDC_NAV_STOP 203
#define ID_TESTS_JAVASCRIPT 32771
#define IDC_STATIC -1
#define IDS_LOGO 1000
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32772
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

View File

@ -0,0 +1,12 @@
// Copyright (c) 2008 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.
// stdafx.cpp : source file that includes just the standard includes
// cefclient.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

46
tests/cefclient/stdafx.h Normal file
View File

@ -0,0 +1,46 @@
// Copyright (c) 2008 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.
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows XP or later.
#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
#endif
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
//#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
//#include <atlbase.h>
//#include <atlstr.h>
// TODO: reference additional headers your program requires here