From 6a52564668032f67de817fc8078191df499ef19c Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Fri, 18 Oct 2013 16:33:56 +0000 Subject: [PATCH] Fix svn:eol-style property. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1470 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- include/cef_auth_callback.h | 128 +- include/cef_drag_data.h | 240 +-- include/cef_drag_handler.h | 132 +- libcef/browser/browser_pref_store.cc | 72 +- libcef/browser/url_request_user_data.cc | 36 +- libcef/browser/url_request_user_data.h | 54 +- libcef/common/drag_data_impl.cc | 126 +- libcef/common/drag_data_impl.h | 74 +- patch/patches/devtools_target.patch | 20 +- patch/patches/webkit_933.patch | 10 +- patch/patches/webkit_popups.patch | 44 +- tests/cefclient/cefclient_osr_widget_gtk.cpp | 986 +++++----- tests/cefclient/cefclient_osr_widget_gtk.h | 180 +- tests/cefclient/cefclient_osr_widget_mac.h | 256 +-- tests/cefclient/cefclient_osr_widget_mac.mm | 1860 +++++++++--------- tests/cefclient/res/osr_test.html | 138 +- tests/cefclient/res/other_tests.html | 64 +- tests/cefclient/res/performance2.html | 884 ++++----- tests/cefclient/window_test_win.cpp | 156 +- tests/unittests/download_unittest.cc | 524 ++--- tests/unittests/life_span_unittest.cc | 612 +++--- tests/unittests/os_rendering_unittest_mac.h | 36 +- tests/unittests/os_rendering_unittest_mac.mm | 78 +- tools/cef_api_hash.py | 492 ++--- tools/date_util.py | 26 +- tools/make_distrib.py | 1426 +++++++------- tools/svn_util.py | 140 +- 27 files changed, 4397 insertions(+), 4397 deletions(-) diff --git a/include/cef_auth_callback.h b/include/cef_auth_callback.h index b5c695320..86d249ad3 100644 --- a/include/cef_auth_callback.h +++ b/include/cef_auth_callback.h @@ -1,64 +1,64 @@ -// Copyright (c) 2013 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. -// -// --------------------------------------------------------------------------- -// -// The contents of this file must follow a specific format in order to -// support the CEF translator tool. See the translator.README.txt file in the -// tools directory for more information. -// - -#ifndef CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ -#define CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ -#pragma once - -#include "include/cef_base.h" - -/// -// Callback interface used for asynchronous continuation of authentication -// requests. -/// -/*--cef(source=library)--*/ -class CefAuthCallback : public virtual CefBase { - public: - /// - // Continue the authentication request. - /// - /*--cef(capi_name=cont)--*/ - virtual void Continue(const CefString& username, - const CefString& password) =0; - - /// - // Cancel the authentication request. - /// - /*--cef()--*/ - virtual void Cancel() =0; -}; - -#endif // CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ +// Copyright (c) 2013 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. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ +#define CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ +#pragma once + +#include "include/cef_base.h" + +/// +// Callback interface used for asynchronous continuation of authentication +// requests. +/// +/*--cef(source=library)--*/ +class CefAuthCallback : public virtual CefBase { + public: + /// + // Continue the authentication request. + /// + /*--cef(capi_name=cont)--*/ + virtual void Continue(const CefString& username, + const CefString& password) =0; + + /// + // Cancel the authentication request. + /// + /*--cef()--*/ + virtual void Cancel() =0; +}; + +#endif // CEF_INCLUDE_CEF_AUTH_CALLBACK_H_ diff --git a/include/cef_drag_data.h b/include/cef_drag_data.h index 2791262d6..58bcc3ed4 100644 --- a/include/cef_drag_data.h +++ b/include/cef_drag_data.h @@ -1,120 +1,120 @@ -// Copyright (c) 2013 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. -// -// --------------------------------------------------------------------------- -// -// The contents of this file must follow a specific format in order to -// support the CEF translator tool. See the translator.README.txt file in the -// tools directory for more information. -// - -#ifndef CEF_INCLUDE_CEF_DRAG_DATA_H_ -#define CEF_INCLUDE_CEF_DRAG_DATA_H_ -#pragma once - -#include "include/cef_base.h" -#include - -/// -// Class used to represent drag data. The methods of this class may be called -// on any thread. -/// -/*--cef(source=library)--*/ -class CefDragData : public virtual CefBase { - public: - /// - // Returns true if the drag data is a link. - /// - /*--cef()--*/ - virtual bool IsLink() =0; - - /// - // Returns true if the drag data is a text or html fragment. - /// - /*--cef()--*/ - virtual bool IsFragment() =0; - - /// - // Returns true if the drag data is a file. - /// - /*--cef()--*/ - virtual bool IsFile() =0; - - /// - // Return the link URL that is being dragged. - /// - /*--cef()--*/ - virtual CefString GetLinkURL() =0; - - /// - // Return the title associated with the link being dragged. - /// - /*--cef()--*/ - virtual CefString GetLinkTitle() =0; - - /// - // Return the metadata, if any, associated with the link being dragged. - /// - /*--cef()--*/ - virtual CefString GetLinkMetadata() =0; - - /// - // Return the plain text fragment that is being dragged. - /// - /*--cef()--*/ - virtual CefString GetFragmentText() =0; - - /// - // Return the text/html fragment that is being dragged. - /// - /*--cef()--*/ - virtual CefString GetFragmentHtml() =0; - - /// - // Return the base URL that the fragment came from. This value is used for - // resolving relative URLs and may be empty. - /// - /*--cef()--*/ - virtual CefString GetFragmentBaseURL() =0; - - /// - // Return the name of the file being dragged out of the browser window. - /// - /*--cef()--*/ - virtual CefString GetFileName() =0; - - /// - // Retrieve the list of file names that are being dragged into the browser - // window. - /// - /*--cef()--*/ - virtual bool GetFileNames(std::vector& names) =0; -}; - -#endif // CEF_INCLUDE_CEF_DRAG_DATA_H_ +// Copyright (c) 2013 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. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DRAG_DATA_H_ +#define CEF_INCLUDE_CEF_DRAG_DATA_H_ +#pragma once + +#include "include/cef_base.h" +#include + +/// +// Class used to represent drag data. The methods of this class may be called +// on any thread. +/// +/*--cef(source=library)--*/ +class CefDragData : public virtual CefBase { + public: + /// + // Returns true if the drag data is a link. + /// + /*--cef()--*/ + virtual bool IsLink() =0; + + /// + // Returns true if the drag data is a text or html fragment. + /// + /*--cef()--*/ + virtual bool IsFragment() =0; + + /// + // Returns true if the drag data is a file. + /// + /*--cef()--*/ + virtual bool IsFile() =0; + + /// + // Return the link URL that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkURL() =0; + + /// + // Return the title associated with the link being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkTitle() =0; + + /// + // Return the metadata, if any, associated with the link being dragged. + /// + /*--cef()--*/ + virtual CefString GetLinkMetadata() =0; + + /// + // Return the plain text fragment that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetFragmentText() =0; + + /// + // Return the text/html fragment that is being dragged. + /// + /*--cef()--*/ + virtual CefString GetFragmentHtml() =0; + + /// + // Return the base URL that the fragment came from. This value is used for + // resolving relative URLs and may be empty. + /// + /*--cef()--*/ + virtual CefString GetFragmentBaseURL() =0; + + /// + // Return the name of the file being dragged out of the browser window. + /// + /*--cef()--*/ + virtual CefString GetFileName() =0; + + /// + // Retrieve the list of file names that are being dragged into the browser + // window. + /// + /*--cef()--*/ + virtual bool GetFileNames(std::vector& names) =0; +}; + +#endif // CEF_INCLUDE_CEF_DRAG_DATA_H_ diff --git a/include/cef_drag_handler.h b/include/cef_drag_handler.h index 2535f770f..7cfc40ba5 100644 --- a/include/cef_drag_handler.h +++ b/include/cef_drag_handler.h @@ -1,66 +1,66 @@ -// Copyright (c) 2013 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. -// -// --------------------------------------------------------------------------- -// -// The contents of this file must follow a specific format in order to -// support the CEF translator tool. See the translator.README.txt file in the -// tools directory for more information. -// - -#ifndef CEF_INCLUDE_CEF_DRAG_HANDLER_H_ -#define CEF_INCLUDE_CEF_DRAG_HANDLER_H_ -#pragma once - -#include "include/cef_base.h" -#include "include/cef_drag_data.h" -#include "include/cef_browser.h" - -/// -// Implement this interface to handle events related to dragging. The methods of -// this class will be called on the UI thread. -/// -/*--cef(source=client)--*/ -class CefDragHandler : public virtual CefBase { - public: - typedef cef_drag_operations_mask_t DragOperationsMask; - - /// - // Called when an external drag event enters the browser window. |dragData| - // contains the drag event data and |mask| represents the type of drag - // operation. Return false for default drag handling behavior or true to - // cancel the drag event. - /// - /*--cef()--*/ - virtual bool OnDragEnter(CefRefPtr browser, - CefRefPtr dragData, - DragOperationsMask mask) { return false; } -}; - -#endif // CEF_INCLUDE_CEF_DRAG_HANDLER_H_ +// Copyright (c) 2013 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. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_DRAG_HANDLER_H_ +#define CEF_INCLUDE_CEF_DRAG_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_drag_data.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to dragging. The methods of +// this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefDragHandler : public virtual CefBase { + public: + typedef cef_drag_operations_mask_t DragOperationsMask; + + /// + // Called when an external drag event enters the browser window. |dragData| + // contains the drag event data and |mask| represents the type of drag + // operation. Return false for default drag handling behavior or true to + // cancel the drag event. + /// + /*--cef()--*/ + virtual bool OnDragEnter(CefRefPtr browser, + CefRefPtr dragData, + DragOperationsMask mask) { return false; } +}; + +#endif // CEF_INCLUDE_CEF_DRAG_HANDLER_H_ diff --git a/libcef/browser/browser_pref_store.cc b/libcef/browser/browser_pref_store.cc index 69303b95c..18eb1090f 100644 --- a/libcef/browser/browser_pref_store.cc +++ b/libcef/browser/browser_pref_store.cc @@ -1,36 +1,36 @@ -// Copyright (c) 2013 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 "libcef/browser/browser_pref_store.h" -#include "libcef/browser/media_capture_devices_dispatcher.h" - -#include "base/command_line.h" -#include "base/prefs/pref_service_builder.h" -#include "base/prefs/pref_registry_simple.h" -#include "base/values.h" -#include "chrome/browser/net/pref_proxy_config_tracker_impl.h" -#include "chrome/browser/prefs/command_line_pref_store.h" -#include "chrome/browser/prefs/proxy_config_dictionary.h" -#include "chrome/common/pref_names.h" - -CefBrowserPrefStore::CefBrowserPrefStore() { -} - -PrefService* CefBrowserPrefStore::CreateService() { - PrefServiceBuilder builder; - builder.WithCommandLinePrefs( - new CommandLinePrefStore(CommandLine::ForCurrentProcess())); - builder.WithUserPrefs(this); - - scoped_refptr registry(new PrefRegistrySimple()); - - // Default settings. - CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry); - PrefProxyConfigTrackerImpl::RegisterPrefs(registry); - - return builder.Create(registry); -} - -CefBrowserPrefStore::~CefBrowserPrefStore() { -} +// Copyright (c) 2013 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 "libcef/browser/browser_pref_store.h" +#include "libcef/browser/media_capture_devices_dispatcher.h" + +#include "base/command_line.h" +#include "base/prefs/pref_service_builder.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/values.h" +#include "chrome/browser/net/pref_proxy_config_tracker_impl.h" +#include "chrome/browser/prefs/command_line_pref_store.h" +#include "chrome/browser/prefs/proxy_config_dictionary.h" +#include "chrome/common/pref_names.h" + +CefBrowserPrefStore::CefBrowserPrefStore() { +} + +PrefService* CefBrowserPrefStore::CreateService() { + PrefServiceBuilder builder; + builder.WithCommandLinePrefs( + new CommandLinePrefStore(CommandLine::ForCurrentProcess())); + builder.WithUserPrefs(this); + + scoped_refptr registry(new PrefRegistrySimple()); + + // Default settings. + CefMediaCaptureDevicesDispatcher::RegisterPrefs(registry); + PrefProxyConfigTrackerImpl::RegisterPrefs(registry); + + return builder.Create(registry); +} + +CefBrowserPrefStore::~CefBrowserPrefStore() { +} diff --git a/libcef/browser/url_request_user_data.cc b/libcef/browser/url_request_user_data.cc index dc23ad0f8..c21885241 100644 --- a/libcef/browser/url_request_user_data.cc +++ b/libcef/browser/url_request_user_data.cc @@ -1,18 +1,18 @@ -// Copyright (c) 2012 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 "libcef/browser/url_request_user_data.h" - -CefURLRequestUserData::CefURLRequestUserData(CefRefPtr client) - : client_(client) {} - -CefURLRequestUserData::~CefURLRequestUserData() {} - -CefRefPtr CefURLRequestUserData::GetClient() { - return client_; -} - -// static -const void* CefURLRequestUserData::kUserDataKey = - static_cast(&CefURLRequestUserData::kUserDataKey); +// Copyright (c) 2012 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 "libcef/browser/url_request_user_data.h" + +CefURLRequestUserData::CefURLRequestUserData(CefRefPtr client) + : client_(client) {} + +CefURLRequestUserData::~CefURLRequestUserData() {} + +CefRefPtr CefURLRequestUserData::GetClient() { + return client_; +} + +// static +const void* CefURLRequestUserData::kUserDataKey = + static_cast(&CefURLRequestUserData::kUserDataKey); diff --git a/libcef/browser/url_request_user_data.h b/libcef/browser/url_request_user_data.h index ea02c3c68..37b8c0253 100644 --- a/libcef/browser/url_request_user_data.h +++ b/libcef/browser/url_request_user_data.h @@ -1,27 +1,27 @@ -// Copyright (c) 2012 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 CEF_LIBCEF_BROWSER_URL_REQUEST_USER_DATA_H_ -#define CEF_LIBCEF_BROWSER_URL_REQUEST_USER_DATA_H_ - -#include "include/cef_base.h" -#include "base/supports_user_data.h" - -#include "include/cef_urlrequest.h" - -// Used to annotate all URLRequests for which the request can be associated -// with the CefURLRequestClient. -class CefURLRequestUserData : public base::SupportsUserData::Data { - public: - CefURLRequestUserData(CefRefPtr client); - virtual ~CefURLRequestUserData(); - - CefRefPtr GetClient(); - static const void* kUserDataKey; - -private: - CefRefPtr client_; -}; - -#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_USER_DATA_H_ +// Copyright (c) 2012 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 CEF_LIBCEF_BROWSER_URL_REQUEST_USER_DATA_H_ +#define CEF_LIBCEF_BROWSER_URL_REQUEST_USER_DATA_H_ + +#include "include/cef_base.h" +#include "base/supports_user_data.h" + +#include "include/cef_urlrequest.h" + +// Used to annotate all URLRequests for which the request can be associated +// with the CefURLRequestClient. +class CefURLRequestUserData : public base::SupportsUserData::Data { + public: + CefURLRequestUserData(CefRefPtr client); + virtual ~CefURLRequestUserData(); + + CefRefPtr GetClient(); + static const void* kUserDataKey; + +private: + CefRefPtr client_; +}; + +#endif // CEF_LIBCEF_BROWSER_URL_REQUEST_USER_DATA_H_ diff --git a/libcef/common/drag_data_impl.cc b/libcef/common/drag_data_impl.cc index eae50e963..969ae24e4 100644 --- a/libcef/common/drag_data_impl.cc +++ b/libcef/common/drag_data_impl.cc @@ -1,63 +1,63 @@ -// Copyright (c) 2013 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 "libcef/common/drag_data_impl.h" -#include "base/files/file_path.h" - -CefDragDataImpl::CefDragDataImpl(const content::DropData& data) - : data_(data) { -} - -bool CefDragDataImpl::IsLink() { - return (data_.url.is_valid() && data_.file_description_filename.empty()); -} - -bool CefDragDataImpl::IsFragment() { - return (!data_.url.is_valid() && data_.file_description_filename.empty() && - data_.filenames.empty()); -} - -bool CefDragDataImpl::IsFile() { - return (!data_.file_description_filename.empty() || !data_.filenames.empty()); -} - -CefString CefDragDataImpl::GetLinkURL() { - return data_.url.spec(); -} - -CefString CefDragDataImpl::GetLinkTitle() { - return data_.url_title; -} - -CefString CefDragDataImpl::GetLinkMetadata() { - return data_.download_metadata; -} - -CefString CefDragDataImpl::GetFragmentText() { - return data_.text.is_null() ? CefString() : CefString(data_.text.string()); -} - -CefString CefDragDataImpl::GetFragmentHtml() { - return data_.html.is_null() ? CefString() : CefString(data_.html.string()); -} - -CefString CefDragDataImpl::GetFragmentBaseURL() { - return data_.html_base_url.spec(); -} - -CefString CefDragDataImpl::GetFileName() { - return data_.file_description_filename; -} - -bool CefDragDataImpl::GetFileNames(std::vector& names) { - if (data_.filenames.empty()) - return false; - - std::vector::const_iterator it = - data_.filenames.begin(); - for (; it != data_.filenames.end(); ++it) - names.push_back(it->path); - - return true; -} +// Copyright (c) 2013 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 "libcef/common/drag_data_impl.h" +#include "base/files/file_path.h" + +CefDragDataImpl::CefDragDataImpl(const content::DropData& data) + : data_(data) { +} + +bool CefDragDataImpl::IsLink() { + return (data_.url.is_valid() && data_.file_description_filename.empty()); +} + +bool CefDragDataImpl::IsFragment() { + return (!data_.url.is_valid() && data_.file_description_filename.empty() && + data_.filenames.empty()); +} + +bool CefDragDataImpl::IsFile() { + return (!data_.file_description_filename.empty() || !data_.filenames.empty()); +} + +CefString CefDragDataImpl::GetLinkURL() { + return data_.url.spec(); +} + +CefString CefDragDataImpl::GetLinkTitle() { + return data_.url_title; +} + +CefString CefDragDataImpl::GetLinkMetadata() { + return data_.download_metadata; +} + +CefString CefDragDataImpl::GetFragmentText() { + return data_.text.is_null() ? CefString() : CefString(data_.text.string()); +} + +CefString CefDragDataImpl::GetFragmentHtml() { + return data_.html.is_null() ? CefString() : CefString(data_.html.string()); +} + +CefString CefDragDataImpl::GetFragmentBaseURL() { + return data_.html_base_url.spec(); +} + +CefString CefDragDataImpl::GetFileName() { + return data_.file_description_filename; +} + +bool CefDragDataImpl::GetFileNames(std::vector& names) { + if (data_.filenames.empty()) + return false; + + std::vector::const_iterator it = + data_.filenames.begin(); + for (; it != data_.filenames.end(); ++it) + names.push_back(it->path); + + return true; +} diff --git a/libcef/common/drag_data_impl.h b/libcef/common/drag_data_impl.h index 882cb172f..17bbd1493 100644 --- a/libcef/common/drag_data_impl.h +++ b/libcef/common/drag_data_impl.h @@ -1,37 +1,37 @@ -// Copyright (c) 2013 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 CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_ -#define CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_ -#pragma once - -#include - -#include "include/cef_drag_data.h" -#include "content/public/common/drop_data.h" - -// Implementation of CefDragData. -class CefDragDataImpl : public CefDragData { - public: - explicit CefDragDataImpl(const content::DropData& data); - - virtual bool IsLink(); - virtual bool IsFragment(); - virtual bool IsFile(); - virtual CefString GetLinkURL(); - virtual CefString GetLinkTitle(); - virtual CefString GetLinkMetadata(); - virtual CefString GetFragmentText(); - virtual CefString GetFragmentHtml(); - virtual CefString GetFragmentBaseURL(); - virtual CefString GetFileName(); - virtual bool GetFileNames(std::vector& names); - - protected: - content::DropData data_; - - IMPLEMENT_REFCOUNTING(CefDragDataImpl); -}; - -#endif // CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_ +// Copyright (c) 2013 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 CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_ +#define CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_ +#pragma once + +#include + +#include "include/cef_drag_data.h" +#include "content/public/common/drop_data.h" + +// Implementation of CefDragData. +class CefDragDataImpl : public CefDragData { + public: + explicit CefDragDataImpl(const content::DropData& data); + + virtual bool IsLink(); + virtual bool IsFragment(); + virtual bool IsFile(); + virtual CefString GetLinkURL(); + virtual CefString GetLinkTitle(); + virtual CefString GetLinkMetadata(); + virtual CefString GetFragmentText(); + virtual CefString GetFragmentHtml(); + virtual CefString GetFragmentBaseURL(); + virtual CefString GetFileName(); + virtual bool GetFileNames(std::vector& names); + + protected: + content::DropData data_; + + IMPLEMENT_REFCOUNTING(CefDragDataImpl); +}; + +#endif // CEF_LIBCEF_COMMON_DRAG_DATA_IMPL_H_ diff --git a/patch/patches/devtools_target.patch b/patch/patches/devtools_target.patch index ac5dd7ff7..ec3538a4b 100644 --- a/patch/patches/devtools_target.patch +++ b/patch/patches/devtools_target.patch @@ -1,8 +1,8 @@ -Index: browser/devtools/devtools_http_handler_impl.cc -=================================================================== ---- browser/devtools/devtools_http_handler_impl.cc (revision 228917) -+++ browser/devtools/devtools_http_handler_impl.cc (working copy) -@@ -542,9 +542,17 @@ +Index: browser/devtools/devtools_http_handler_impl.cc +=================================================================== +--- browser/devtools/devtools_http_handler_impl.cc (revision 228917) ++++ browser/devtools/devtools_http_handler_impl.cc (working copy) +@@ -542,9 +542,17 @@ DevToolsTarget* DevToolsHttpHandlerImpl::GetTarget(const std::string& id) { TargetMap::const_iterator it = target_map_.find(id); @@ -23,11 +23,11 @@ Index: browser/devtools/devtools_http_handler_impl.cc } void DevToolsHttpHandlerImpl::OnThumbnailRequestUI( -Index: public/browser/devtools_http_handler_delegate.h -=================================================================== ---- public/browser/devtools_http_handler_delegate.h (revision 228917) -+++ public/browser/devtools_http_handler_delegate.h (working copy) -@@ -39,6 +39,13 @@ +Index: public/browser/devtools_http_handler_delegate.h +=================================================================== +--- public/browser/devtools_http_handler_delegate.h (revision 228917) ++++ public/browser/devtools_http_handler_delegate.h (working copy) +@@ -39,6 +39,13 @@ // Creates new inspectable target. virtual scoped_ptr CreateNewTarget() = 0; diff --git a/patch/patches/webkit_933.patch b/patch/patches/webkit_933.patch index 0e0ef1700..18b01f968 100644 --- a/patch/patches/webkit_933.patch +++ b/patch/patches/webkit_933.patch @@ -1,8 +1,8 @@ -Index: WebNode.cpp -=================================================================== ---- WebNode.cpp (revision 158192) -+++ WebNode.cpp (working copy) -@@ -175,7 +175,7 @@ +Index: WebNode.cpp +=================================================================== +--- WebNode.cpp (revision 158192) ++++ WebNode.cpp (working copy) +@@ -175,7 +175,7 @@ void WebNode::addEventListener(const WebString& eventType, WebDOMEventListener* listener, bool useCapture) { // Please do not add more eventTypes to this list without an API review. diff --git a/patch/patches/webkit_popups.patch b/patch/patches/webkit_popups.patch index 9cf2d259c..90da8bba0 100644 --- a/patch/patches/webkit_popups.patch +++ b/patch/patches/webkit_popups.patch @@ -1,8 +1,8 @@ -Index: public/web/WebView.h -=================================================================== ---- public/web/WebView.h (revision 159695) -+++ public/web/WebView.h (working copy) -@@ -447,6 +447,7 @@ +Index: public/web/WebView.h +=================================================================== +--- public/web/WebView.h (revision 159695) ++++ public/web/WebView.h (working copy) +@@ -447,6 +447,7 @@ // Sets whether select popup menus should be rendered by the browser. BLINK_EXPORT static void setUseExternalPopupMenus(bool); @@ -10,11 +10,11 @@ Index: public/web/WebView.h // Visited link state -------------------------------------------------- -Index: Source/web/ChromeClientImpl.cpp -=================================================================== ---- Source/web/ChromeClientImpl.cpp (revision 159695) -+++ Source/web/ChromeClientImpl.cpp (working copy) -@@ -875,7 +875,7 @@ +Index: Source/web/ChromeClientImpl.cpp +=================================================================== +--- Source/web/ChromeClientImpl.cpp (revision 159695) ++++ Source/web/ChromeClientImpl.cpp (working copy) +@@ -875,7 +875,7 @@ PassRefPtr ChromeClientImpl::createPopupMenu(Frame& frame, PopupMenuClient* client) const { @@ -23,11 +23,11 @@ Index: Source/web/ChromeClientImpl.cpp return adoptRef(new ExternalPopupMenu(frame, client, m_webView->client())); return adoptRef(new PopupMenuChromium(frame, client)); -Index: Source/web/WebViewImpl.cpp -=================================================================== ---- Source/web/WebViewImpl.cpp (revision 159695) -+++ Source/web/WebViewImpl.cpp (working copy) -@@ -411,6 +411,7 @@ +Index: Source/web/WebViewImpl.cpp +=================================================================== +--- Source/web/WebViewImpl.cpp (revision 159695) ++++ Source/web/WebViewImpl.cpp (working copy) +@@ -411,6 +411,7 @@ , m_fakePageScaleAnimationPageScaleFactor(0) , m_fakePageScaleAnimationUseAnchor(false) , m_contextMenuAllowed(false) @@ -35,7 +35,7 @@ Index: Source/web/WebViewImpl.cpp , m_doingDragAndDrop(false) , m_ignoreInputEvents(false) , m_compositorDeviceScaleFactorOverride(0) -@@ -3751,9 +3752,14 @@ +@@ -3751,9 +3752,14 @@ updateLayerTreeViewport(); } @@ -51,11 +51,11 @@ Index: Source/web/WebViewImpl.cpp } void WebViewImpl::startDragging(Frame* frame, -Index: Source/web/WebViewImpl.h -=================================================================== ---- Source/web/WebViewImpl.h (revision 159695) -+++ Source/web/WebViewImpl.h (working copy) -@@ -424,7 +424,8 @@ +Index: Source/web/WebViewImpl.h +=================================================================== +--- Source/web/WebViewImpl.h (revision 159695) ++++ Source/web/WebViewImpl.h (working copy) +@@ -424,7 +424,8 @@ // Returns true if popup menus should be rendered by the browser, false if // they should be rendered by WebKit (which is the default). @@ -65,7 +65,7 @@ Index: Source/web/WebViewImpl.h bool contextMenuAllowed() const { -@@ -727,6 +728,8 @@ +@@ -727,6 +728,8 @@ bool m_contextMenuAllowed; diff --git a/tests/cefclient/cefclient_osr_widget_gtk.cpp b/tests/cefclient/cefclient_osr_widget_gtk.cpp index 373ef1ab4..2320cb381 100644 --- a/tests/cefclient/cefclient_osr_widget_gtk.cpp +++ b/tests/cefclient/cefclient_osr_widget_gtk.cpp @@ -1,493 +1,493 @@ -// Copyright (c) 2013 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 "cefclient/cefclient_osr_widget_gtk.h" - -// This value is defined in build/common.gypi and must be undefined here -// in order for gtkglext to compile. -#undef GTK_DISABLE_SINGLE_INCLUDES - -#include -#include -#include -#include -#include -#include - -#include "include/cef_runnable.h" -#include "cefclient/util.h" - -namespace { - -gint glarea_size_allocation(GtkWidget* widget, - GtkAllocation* allocation, - OSRWindow* window) { - CefRefPtr host = window->GetBrowserHost(); - host->WasResized(); - return TRUE; -} - -int get_cef_state_modifiers(guint state) { - int modifiers = 0; - if (state & GDK_SHIFT_MASK) - modifiers |= EVENTFLAG_SHIFT_DOWN; - if (state & GDK_LOCK_MASK) - modifiers |= EVENTFLAG_CAPS_LOCK_ON; - if (state & GDK_CONTROL_MASK) - modifiers |= EVENTFLAG_CONTROL_DOWN; - if (state & GDK_MOD1_MASK) - modifiers |= EVENTFLAG_ALT_DOWN; - if (state & GDK_BUTTON1_MASK) - modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; - if (state & GDK_BUTTON2_MASK) - modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; - if (state & GDK_BUTTON3_MASK) - modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; - return modifiers; -} - -gint glarea_click_event(GtkWidget* widget, - GdkEventButton* event, - OSRWindow* window) { - CefRefPtr host = window->GetBrowserHost(); - - CefBrowserHost::MouseButtonType button_type = MBT_LEFT; - switch (event->button) { - case 1: - break; - case 2: - button_type = MBT_MIDDLE; - break; - case 3: - button_type = MBT_RIGHT; - break; - default: - // Other mouse buttons are not handled here. - return FALSE; - } - - CefMouseEvent mouse_event; - mouse_event.x = event->x; - mouse_event.y = event->y; - window->ApplyPopupOffset(mouse_event.x, mouse_event.y); - mouse_event.modifiers = get_cef_state_modifiers(event->state); - - bool mouse_up = (event->type == GDK_BUTTON_RELEASE); - if (!mouse_up) - gtk_widget_grab_focus(widget); - - int click_count = 1; - switch (event->type) { - case GDK_2BUTTON_PRESS: - click_count = 2; - break; - case GDK_3BUTTON_PRESS: - click_count = 3; - break; - default: - break; - } - - host->SendMouseClickEvent(mouse_event, button_type, mouse_up, click_count); - return TRUE; -} - -gint glarea_move_event(GtkWidget* widget, - GdkEventMotion* event, - OSRWindow* window) { - gint x, y; - GdkModifierType state; - - if (event->is_hint) { - gdk_window_get_pointer(event->window, &x, &y, &state); - } else { - x = (gint)event->x; - y = (gint)event->y; - state = (GdkModifierType)event->state; - } - - CefRefPtr host = window->GetBrowserHost(); - - CefMouseEvent mouse_event; - mouse_event.x = x; - mouse_event.y = y; - window->ApplyPopupOffset(mouse_event.x, mouse_event.y); - mouse_event.modifiers = get_cef_state_modifiers(state); - - bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY); - - host->SendMouseMoveEvent(mouse_event, mouse_leave); - return TRUE; -} - -gint glarea_scroll_event(GtkWidget* widget, - GdkEventScroll* event, - OSRWindow* window) { - CefRefPtr host = window->GetBrowserHost(); - - CefMouseEvent mouse_event; - mouse_event.x = event->x; - mouse_event.y = event->y; - window->ApplyPopupOffset(mouse_event.x, mouse_event.y); - mouse_event.modifiers = get_cef_state_modifiers(event->state); - - static const int scrollbarPixelsPerGtkTick = 40; - int deltaX = 0; - int deltaY = 0; - switch (event->direction) { - case GDK_SCROLL_UP: - deltaY = scrollbarPixelsPerGtkTick; - break; - case GDK_SCROLL_DOWN: - deltaY = -scrollbarPixelsPerGtkTick; - break; - case GDK_SCROLL_LEFT: - deltaX = scrollbarPixelsPerGtkTick; - break; - case GDK_SCROLL_RIGHT: - deltaX = -scrollbarPixelsPerGtkTick; - break; - } - - host->SendMouseWheelEvent(mouse_event, deltaX, deltaY); - return TRUE; -} - -gint glarea_key_event(GtkWidget* widget, - GdkEventKey* event, - OSRWindow* window) { - CefRefPtr host = window->GetBrowserHost(); - - CefKeyEvent key_event; - key_event.native_key_code = event->keyval; - key_event.modifiers = get_cef_state_modifiers(event->state); - - if (event->type == GDK_KEY_PRESS) { - key_event.type = KEYEVENT_RAWKEYDOWN; - host->SendKeyEvent(key_event); - } else { - // Need to send both KEYUP and CHAR events. - key_event.type = KEYEVENT_KEYUP; - host->SendKeyEvent(key_event); - key_event.type = KEYEVENT_CHAR; - host->SendKeyEvent(key_event); - } - - return TRUE; -} - -gint glarea_focus_event(GtkWidget* widget, - GdkEventFocus* event, - OSRWindow* window) { - CefRefPtr host = window->GetBrowserHost(); - host->SendFocusEvent(event->in == TRUE); - return TRUE; -} - -void widget_get_rect_in_screen(GtkWidget* widget, GdkRectangle* r) { - gint x, y, w, h; - GdkRectangle extents; - - GdkWindow* window = gtk_widget_get_parent_window(widget); - - // Get parent's left-top screen coordinates. - gdk_window_get_root_origin(window, &x, &y); - // Get parent's width and height. - gdk_drawable_get_size(window, &w, &h); - // Get parent's extents including decorations. - gdk_window_get_frame_extents(window, &extents); - - // X and Y calculations assume that left, right and bottom border sizes are - // all the same. - const gint border = (extents.width - w) / 2; - r->x = x + border + widget->allocation.x; - r->y = y + (extents.height - h) - border + widget->allocation.y; - r->width = widget->allocation.width; - r->height = widget->allocation.height; -} - -class ScopedGLContext { - public: - ScopedGLContext(GtkWidget* widget, bool swap_buffers) - : swap_buffers_(swap_buffers) { - GdkGLContext* glcontext = gtk_widget_get_gl_context(widget); - gldrawable_ = gtk_widget_get_gl_drawable(widget); - is_valid_ = gdk_gl_drawable_gl_begin(gldrawable_, glcontext); - } - - virtual ~ScopedGLContext() { - if (is_valid_) { - gdk_gl_drawable_gl_end(gldrawable_); - - if(swap_buffers_) { - if (gdk_gl_drawable_is_double_buffered(gldrawable_)) - gdk_gl_drawable_swap_buffers(gldrawable_); - else - glFlush(); - } - } - } - - bool IsValid() const { return is_valid_; } - - private: - bool swap_buffers_; - GdkGLContext* glcontext_; - GdkGLDrawable* gldrawable_; - bool is_valid_; -}; - -} // namespace - -// static -CefRefPtr OSRWindow::Create(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView) { - ASSERT(browser_provider); - if (!browser_provider) - return NULL; - - return new OSRWindow(browser_provider, transparent, parentView); -} - -// static -CefRefPtr OSRWindow::From( - CefRefPtr renderHandler) { - return static_cast(renderHandler.get()); -} - -void OSRWindow::OnBeforeClose(CefRefPtr browser) { - // Disconnect all signal handlers that reference |this|. - g_signal_handlers_disconnect_matched(glarea_, G_SIGNAL_MATCH_DATA, 0, 0, - NULL, NULL, this); - - DisableGL(); -} - -bool OSRWindow::GetViewRect(CefRefPtr browser, - CefRect& rect) { - if (!glarea_) - return false; - - // The simulated screen and view rectangle are the same. This is necessary - // for popup menus to be located and sized inside the view. - rect.x = rect.y = 0; - rect.width = glarea_->allocation.width; - rect.height = glarea_->allocation.height; - return true; -} - -bool OSRWindow::GetScreenPoint(CefRefPtr browser, - int viewX, - int viewY, - int& screenX, - int& screenY) { - GdkRectangle screen_rect; - widget_get_rect_in_screen(glarea_, &screen_rect); - screenX = screen_rect.x + viewX; - screenY = screen_rect.y + viewY; - return true; -} - -void OSRWindow::OnPopupShow(CefRefPtr browser, - bool show) { - if (!show) { - CefRect dirty_rect = renderer_.popup_rect(); - renderer_.ClearPopupRects(); - browser->GetHost()->Invalidate(dirty_rect, PET_VIEW); - } - renderer_.OnPopupShow(browser, show); -} - -void OSRWindow::OnPopupSize(CefRefPtr browser, - const CefRect& rect) { - renderer_.OnPopupSize(browser, rect); -} - -void OSRWindow::OnPaint(CefRefPtr browser, - PaintElementType type, - const RectList& dirtyRects, - const void* buffer, - int width, int height) { - if (painting_popup_) { - renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height); - return; - } - - if (!gl_enabled_) - EnableGL(); - - ScopedGLContext scoped_gl_context(glarea_, true); - if (!scoped_gl_context.IsValid()) - return; - - renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height); - if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) { - painting_popup_ = true; - CefRect client_popup_rect(0, 0, - renderer_.popup_rect().width, - renderer_.popup_rect().height); - browser->GetHost()->Invalidate(client_popup_rect, PET_POPUP); - painting_popup_ = false; - } - renderer_.Render(); -} - -void OSRWindow::OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) { - GtkWidget* window = gtk_widget_get_toplevel(glarea_); - GdkWindow* gdk_window = gtk_widget_get_window(window); - if (cursor->type == GDK_LAST_CURSOR) - cursor = NULL; - gdk_window_set_cursor(gdk_window, cursor); -} - -void OSRWindow::Invalidate() { - if (!CefCurrentlyOn(TID_UI)) { - CefPostTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Invalidate)); - return; - } - - // Don't post another task if the previous task is still pending. - if (render_task_pending_) - return; - - render_task_pending_ = true; - - // Render at 30fps. - static const int kRenderDelay = 1000 / 30; - CefPostDelayedTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Render), - kRenderDelay); -} - -bool OSRWindow::IsOverPopupWidget(int x, int y) const { - const CefRect& rc = renderer_.popup_rect(); - int popup_right = rc.x + rc.width; - int popup_bottom = rc.y + rc.height; - return (x >= rc.x) && (x < popup_right) && - (y >= rc.y) && (y < popup_bottom); -} - -int OSRWindow::GetPopupXOffset() const { - return renderer_.original_popup_rect().x - renderer_.popup_rect().x; -} - -int OSRWindow::GetPopupYOffset() const { - return renderer_.original_popup_rect().y - renderer_.popup_rect().y; -} - -void OSRWindow::ApplyPopupOffset(int& x, int& y) const { - if (IsOverPopupWidget(x, y)) { - x += GetPopupXOffset(); - y += GetPopupYOffset(); - } -} - -OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView) - : renderer_(transparent), - browser_provider_(browser_provider), - gl_enabled_(false), - painting_popup_(false), - render_task_pending_(false) { - glarea_ = gtk_drawing_area_new(); - ASSERT(glarea_); - - GdkGLConfig* glconfig = gdk_gl_config_new_by_mode( - static_cast(GDK_GL_MODE_RGB | - GDK_GL_MODE_DEPTH | - GDK_GL_MODE_DOUBLE)); - ASSERT(glconfig); - - gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE, - GDK_GL_RGBA_TYPE); - - gtk_widget_set_can_focus(glarea_, TRUE); - - g_signal_connect(G_OBJECT(glarea_), "size_allocate", - G_CALLBACK(glarea_size_allocation), this); - - gtk_widget_set_events(glarea_, - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK | - GDK_SCROLL_MASK | - GDK_FOCUS_CHANGE_MASK); - g_signal_connect(G_OBJECT(glarea_), "button_press_event", - G_CALLBACK(glarea_click_event), this); - g_signal_connect(G_OBJECT(glarea_), "button_release_event", - G_CALLBACK(glarea_click_event), this); - g_signal_connect(G_OBJECT(glarea_), "key_press_event", - G_CALLBACK(glarea_key_event), this); - g_signal_connect(G_OBJECT(glarea_), "key_release_event", - G_CALLBACK(glarea_key_event), this); - g_signal_connect(G_OBJECT(glarea_), "enter_notify_event", - G_CALLBACK(glarea_move_event), this); - g_signal_connect(G_OBJECT(glarea_), "leave_notify_event", - G_CALLBACK(glarea_move_event), this); - g_signal_connect(G_OBJECT(glarea_), "motion_notify_event", - G_CALLBACK(glarea_move_event), this); - g_signal_connect(G_OBJECT(glarea_), "scroll_event", - G_CALLBACK(glarea_scroll_event), this); - g_signal_connect(G_OBJECT(glarea_), "focus_in_event", - G_CALLBACK(glarea_focus_event), this); - g_signal_connect(G_OBJECT(glarea_), "focus_out_event", - G_CALLBACK(glarea_focus_event), this); - - gtk_container_add(GTK_CONTAINER(parentView), glarea_); -} - -OSRWindow::~OSRWindow() { -} - -void OSRWindow::Render() { - ASSERT(CefCurrentlyOn(TID_UI)); - if (render_task_pending_) - render_task_pending_ = false; - - if (!gl_enabled_) - EnableGL(); - - ScopedGLContext scoped_gl_context(glarea_, true); - if (!scoped_gl_context.IsValid()) - return; - - renderer_.Render(); -} - -void OSRWindow::EnableGL() { - ASSERT(CefCurrentlyOn(TID_UI)); - if (gl_enabled_) - return; - - ScopedGLContext scoped_gl_context(glarea_, false); - if (!scoped_gl_context.IsValid()) - return; - - renderer_.Initialize(); - - gl_enabled_ = true; -} - -void OSRWindow::DisableGL() { - ASSERT(CefCurrentlyOn(TID_UI)); - - if (!gl_enabled_) - return; - - ScopedGLContext scoped_gl_context(glarea_, false); - if (!scoped_gl_context.IsValid()) - return; - - renderer_.Cleanup(); - - gl_enabled_ = false; -} - +// Copyright (c) 2013 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 "cefclient/cefclient_osr_widget_gtk.h" + +// This value is defined in build/common.gypi and must be undefined here +// in order for gtkglext to compile. +#undef GTK_DISABLE_SINGLE_INCLUDES + +#include +#include +#include +#include +#include +#include + +#include "include/cef_runnable.h" +#include "cefclient/util.h" + +namespace { + +gint glarea_size_allocation(GtkWidget* widget, + GtkAllocation* allocation, + OSRWindow* window) { + CefRefPtr host = window->GetBrowserHost(); + host->WasResized(); + return TRUE; +} + +int get_cef_state_modifiers(guint state) { + int modifiers = 0; + if (state & GDK_SHIFT_MASK) + modifiers |= EVENTFLAG_SHIFT_DOWN; + if (state & GDK_LOCK_MASK) + modifiers |= EVENTFLAG_CAPS_LOCK_ON; + if (state & GDK_CONTROL_MASK) + modifiers |= EVENTFLAG_CONTROL_DOWN; + if (state & GDK_MOD1_MASK) + modifiers |= EVENTFLAG_ALT_DOWN; + if (state & GDK_BUTTON1_MASK) + modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; + if (state & GDK_BUTTON2_MASK) + modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; + if (state & GDK_BUTTON3_MASK) + modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; + return modifiers; +} + +gint glarea_click_event(GtkWidget* widget, + GdkEventButton* event, + OSRWindow* window) { + CefRefPtr host = window->GetBrowserHost(); + + CefBrowserHost::MouseButtonType button_type = MBT_LEFT; + switch (event->button) { + case 1: + break; + case 2: + button_type = MBT_MIDDLE; + break; + case 3: + button_type = MBT_RIGHT; + break; + default: + // Other mouse buttons are not handled here. + return FALSE; + } + + CefMouseEvent mouse_event; + mouse_event.x = event->x; + mouse_event.y = event->y; + window->ApplyPopupOffset(mouse_event.x, mouse_event.y); + mouse_event.modifiers = get_cef_state_modifiers(event->state); + + bool mouse_up = (event->type == GDK_BUTTON_RELEASE); + if (!mouse_up) + gtk_widget_grab_focus(widget); + + int click_count = 1; + switch (event->type) { + case GDK_2BUTTON_PRESS: + click_count = 2; + break; + case GDK_3BUTTON_PRESS: + click_count = 3; + break; + default: + break; + } + + host->SendMouseClickEvent(mouse_event, button_type, mouse_up, click_count); + return TRUE; +} + +gint glarea_move_event(GtkWidget* widget, + GdkEventMotion* event, + OSRWindow* window) { + gint x, y; + GdkModifierType state; + + if (event->is_hint) { + gdk_window_get_pointer(event->window, &x, &y, &state); + } else { + x = (gint)event->x; + y = (gint)event->y; + state = (GdkModifierType)event->state; + } + + CefRefPtr host = window->GetBrowserHost(); + + CefMouseEvent mouse_event; + mouse_event.x = x; + mouse_event.y = y; + window->ApplyPopupOffset(mouse_event.x, mouse_event.y); + mouse_event.modifiers = get_cef_state_modifiers(state); + + bool mouse_leave = (event->type == GDK_LEAVE_NOTIFY); + + host->SendMouseMoveEvent(mouse_event, mouse_leave); + return TRUE; +} + +gint glarea_scroll_event(GtkWidget* widget, + GdkEventScroll* event, + OSRWindow* window) { + CefRefPtr host = window->GetBrowserHost(); + + CefMouseEvent mouse_event; + mouse_event.x = event->x; + mouse_event.y = event->y; + window->ApplyPopupOffset(mouse_event.x, mouse_event.y); + mouse_event.modifiers = get_cef_state_modifiers(event->state); + + static const int scrollbarPixelsPerGtkTick = 40; + int deltaX = 0; + int deltaY = 0; + switch (event->direction) { + case GDK_SCROLL_UP: + deltaY = scrollbarPixelsPerGtkTick; + break; + case GDK_SCROLL_DOWN: + deltaY = -scrollbarPixelsPerGtkTick; + break; + case GDK_SCROLL_LEFT: + deltaX = scrollbarPixelsPerGtkTick; + break; + case GDK_SCROLL_RIGHT: + deltaX = -scrollbarPixelsPerGtkTick; + break; + } + + host->SendMouseWheelEvent(mouse_event, deltaX, deltaY); + return TRUE; +} + +gint glarea_key_event(GtkWidget* widget, + GdkEventKey* event, + OSRWindow* window) { + CefRefPtr host = window->GetBrowserHost(); + + CefKeyEvent key_event; + key_event.native_key_code = event->keyval; + key_event.modifiers = get_cef_state_modifiers(event->state); + + if (event->type == GDK_KEY_PRESS) { + key_event.type = KEYEVENT_RAWKEYDOWN; + host->SendKeyEvent(key_event); + } else { + // Need to send both KEYUP and CHAR events. + key_event.type = KEYEVENT_KEYUP; + host->SendKeyEvent(key_event); + key_event.type = KEYEVENT_CHAR; + host->SendKeyEvent(key_event); + } + + return TRUE; +} + +gint glarea_focus_event(GtkWidget* widget, + GdkEventFocus* event, + OSRWindow* window) { + CefRefPtr host = window->GetBrowserHost(); + host->SendFocusEvent(event->in == TRUE); + return TRUE; +} + +void widget_get_rect_in_screen(GtkWidget* widget, GdkRectangle* r) { + gint x, y, w, h; + GdkRectangle extents; + + GdkWindow* window = gtk_widget_get_parent_window(widget); + + // Get parent's left-top screen coordinates. + gdk_window_get_root_origin(window, &x, &y); + // Get parent's width and height. + gdk_drawable_get_size(window, &w, &h); + // Get parent's extents including decorations. + gdk_window_get_frame_extents(window, &extents); + + // X and Y calculations assume that left, right and bottom border sizes are + // all the same. + const gint border = (extents.width - w) / 2; + r->x = x + border + widget->allocation.x; + r->y = y + (extents.height - h) - border + widget->allocation.y; + r->width = widget->allocation.width; + r->height = widget->allocation.height; +} + +class ScopedGLContext { + public: + ScopedGLContext(GtkWidget* widget, bool swap_buffers) + : swap_buffers_(swap_buffers) { + GdkGLContext* glcontext = gtk_widget_get_gl_context(widget); + gldrawable_ = gtk_widget_get_gl_drawable(widget); + is_valid_ = gdk_gl_drawable_gl_begin(gldrawable_, glcontext); + } + + virtual ~ScopedGLContext() { + if (is_valid_) { + gdk_gl_drawable_gl_end(gldrawable_); + + if(swap_buffers_) { + if (gdk_gl_drawable_is_double_buffered(gldrawable_)) + gdk_gl_drawable_swap_buffers(gldrawable_); + else + glFlush(); + } + } + } + + bool IsValid() const { return is_valid_; } + + private: + bool swap_buffers_; + GdkGLContext* glcontext_; + GdkGLDrawable* gldrawable_; + bool is_valid_; +}; + +} // namespace + +// static +CefRefPtr OSRWindow::Create(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView) { + ASSERT(browser_provider); + if (!browser_provider) + return NULL; + + return new OSRWindow(browser_provider, transparent, parentView); +} + +// static +CefRefPtr OSRWindow::From( + CefRefPtr renderHandler) { + return static_cast(renderHandler.get()); +} + +void OSRWindow::OnBeforeClose(CefRefPtr browser) { + // Disconnect all signal handlers that reference |this|. + g_signal_handlers_disconnect_matched(glarea_, G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, this); + + DisableGL(); +} + +bool OSRWindow::GetViewRect(CefRefPtr browser, + CefRect& rect) { + if (!glarea_) + return false; + + // The simulated screen and view rectangle are the same. This is necessary + // for popup menus to be located and sized inside the view. + rect.x = rect.y = 0; + rect.width = glarea_->allocation.width; + rect.height = glarea_->allocation.height; + return true; +} + +bool OSRWindow::GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) { + GdkRectangle screen_rect; + widget_get_rect_in_screen(glarea_, &screen_rect); + screenX = screen_rect.x + viewX; + screenY = screen_rect.y + viewY; + return true; +} + +void OSRWindow::OnPopupShow(CefRefPtr browser, + bool show) { + if (!show) { + CefRect dirty_rect = renderer_.popup_rect(); + renderer_.ClearPopupRects(); + browser->GetHost()->Invalidate(dirty_rect, PET_VIEW); + } + renderer_.OnPopupShow(browser, show); +} + +void OSRWindow::OnPopupSize(CefRefPtr browser, + const CefRect& rect) { + renderer_.OnPopupSize(browser, rect); +} + +void OSRWindow::OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer, + int width, int height) { + if (painting_popup_) { + renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height); + return; + } + + if (!gl_enabled_) + EnableGL(); + + ScopedGLContext scoped_gl_context(glarea_, true); + if (!scoped_gl_context.IsValid()) + return; + + renderer_.OnPaint(browser, type, dirtyRects, buffer, width, height); + if (type == PET_VIEW && !renderer_.popup_rect().IsEmpty()) { + painting_popup_ = true; + CefRect client_popup_rect(0, 0, + renderer_.popup_rect().width, + renderer_.popup_rect().height); + browser->GetHost()->Invalidate(client_popup_rect, PET_POPUP); + painting_popup_ = false; + } + renderer_.Render(); +} + +void OSRWindow::OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) { + GtkWidget* window = gtk_widget_get_toplevel(glarea_); + GdkWindow* gdk_window = gtk_widget_get_window(window); + if (cursor->type == GDK_LAST_CURSOR) + cursor = NULL; + gdk_window_set_cursor(gdk_window, cursor); +} + +void OSRWindow::Invalidate() { + if (!CefCurrentlyOn(TID_UI)) { + CefPostTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Invalidate)); + return; + } + + // Don't post another task if the previous task is still pending. + if (render_task_pending_) + return; + + render_task_pending_ = true; + + // Render at 30fps. + static const int kRenderDelay = 1000 / 30; + CefPostDelayedTask(TID_UI, NewCefRunnableMethod(this, &OSRWindow::Render), + kRenderDelay); +} + +bool OSRWindow::IsOverPopupWidget(int x, int y) const { + const CefRect& rc = renderer_.popup_rect(); + int popup_right = rc.x + rc.width; + int popup_bottom = rc.y + rc.height; + return (x >= rc.x) && (x < popup_right) && + (y >= rc.y) && (y < popup_bottom); +} + +int OSRWindow::GetPopupXOffset() const { + return renderer_.original_popup_rect().x - renderer_.popup_rect().x; +} + +int OSRWindow::GetPopupYOffset() const { + return renderer_.original_popup_rect().y - renderer_.popup_rect().y; +} + +void OSRWindow::ApplyPopupOffset(int& x, int& y) const { + if (IsOverPopupWidget(x, y)) { + x += GetPopupXOffset(); + y += GetPopupYOffset(); + } +} + +OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView) + : renderer_(transparent), + browser_provider_(browser_provider), + gl_enabled_(false), + painting_popup_(false), + render_task_pending_(false) { + glarea_ = gtk_drawing_area_new(); + ASSERT(glarea_); + + GdkGLConfig* glconfig = gdk_gl_config_new_by_mode( + static_cast(GDK_GL_MODE_RGB | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE)); + ASSERT(glconfig); + + gtk_widget_set_gl_capability(glarea_, glconfig, NULL, TRUE, + GDK_GL_RGBA_TYPE); + + gtk_widget_set_can_focus(glarea_, TRUE); + + g_signal_connect(G_OBJECT(glarea_), "size_allocate", + G_CALLBACK(glarea_size_allocation), this); + + gtk_widget_set_events(glarea_, + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_KEY_PRESS_MASK | + GDK_KEY_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_SCROLL_MASK | + GDK_FOCUS_CHANGE_MASK); + g_signal_connect(G_OBJECT(glarea_), "button_press_event", + G_CALLBACK(glarea_click_event), this); + g_signal_connect(G_OBJECT(glarea_), "button_release_event", + G_CALLBACK(glarea_click_event), this); + g_signal_connect(G_OBJECT(glarea_), "key_press_event", + G_CALLBACK(glarea_key_event), this); + g_signal_connect(G_OBJECT(glarea_), "key_release_event", + G_CALLBACK(glarea_key_event), this); + g_signal_connect(G_OBJECT(glarea_), "enter_notify_event", + G_CALLBACK(glarea_move_event), this); + g_signal_connect(G_OBJECT(glarea_), "leave_notify_event", + G_CALLBACK(glarea_move_event), this); + g_signal_connect(G_OBJECT(glarea_), "motion_notify_event", + G_CALLBACK(glarea_move_event), this); + g_signal_connect(G_OBJECT(glarea_), "scroll_event", + G_CALLBACK(glarea_scroll_event), this); + g_signal_connect(G_OBJECT(glarea_), "focus_in_event", + G_CALLBACK(glarea_focus_event), this); + g_signal_connect(G_OBJECT(glarea_), "focus_out_event", + G_CALLBACK(glarea_focus_event), this); + + gtk_container_add(GTK_CONTAINER(parentView), glarea_); +} + +OSRWindow::~OSRWindow() { +} + +void OSRWindow::Render() { + ASSERT(CefCurrentlyOn(TID_UI)); + if (render_task_pending_) + render_task_pending_ = false; + + if (!gl_enabled_) + EnableGL(); + + ScopedGLContext scoped_gl_context(glarea_, true); + if (!scoped_gl_context.IsValid()) + return; + + renderer_.Render(); +} + +void OSRWindow::EnableGL() { + ASSERT(CefCurrentlyOn(TID_UI)); + if (gl_enabled_) + return; + + ScopedGLContext scoped_gl_context(glarea_, false); + if (!scoped_gl_context.IsValid()) + return; + + renderer_.Initialize(); + + gl_enabled_ = true; +} + +void OSRWindow::DisableGL() { + ASSERT(CefCurrentlyOn(TID_UI)); + + if (!gl_enabled_) + return; + + ScopedGLContext scoped_gl_context(glarea_, false); + if (!scoped_gl_context.IsValid()) + return; + + renderer_.Cleanup(); + + gl_enabled_ = false; +} + diff --git a/tests/cefclient/cefclient_osr_widget_gtk.h b/tests/cefclient/cefclient_osr_widget_gtk.h index 9bab8dae9..10e4b43d1 100644 --- a/tests/cefclient/cefclient_osr_widget_gtk.h +++ b/tests/cefclient/cefclient_osr_widget_gtk.h @@ -1,90 +1,90 @@ -// Copyright (c) 2013 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 CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_ -#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_ -#pragma once - -#include "include/cef_render_handler.h" -#include "cefclient/client_handler.h" -#include "cefclient/osrenderer.h" - -class OSRBrowserProvider { - public: - virtual CefRefPtr GetBrowser() =0; - - protected: - virtual ~OSRBrowserProvider() {} -}; - -class OSRWindow : public ClientHandler::RenderHandler { - public: - // Create a new OSRWindow instance. |browser_provider| must outlive this - // object. - static CefRefPtr Create(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView); - - static CefRefPtr From( - CefRefPtr renderHandler); - - CefWindowHandle GetWindowHandle() const { - return glarea_; - } - CefRefPtr GetBrowserHost() const { - return browser_provider_->GetBrowser()->GetHost(); - } - - // ClientHandler::RenderHandler methods - virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; - - // CefRenderHandler methods - virtual bool GetViewRect(CefRefPtr browser, - CefRect& rect) OVERRIDE; - virtual bool GetScreenPoint(CefRefPtr browser, - int viewX, - int viewY, - int& screenX, - int& screenY) OVERRIDE; - virtual void OnPopupShow(CefRefPtr browser, - bool show) OVERRIDE; - virtual void OnPopupSize(CefRefPtr browser, - const CefRect& rect) OVERRIDE; - virtual void OnPaint(CefRefPtr browser, - PaintElementType type, - const RectList& dirtyRects, - const void* buffer, - int width, - int height) OVERRIDE; - virtual void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) OVERRIDE; - - void Invalidate(); - bool IsOverPopupWidget(int x, int y) const; - int GetPopupXOffset() const; - int GetPopupYOffset() const; - void ApplyPopupOffset(int& x, int& y) const; - - private: - OSRWindow(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView); - virtual ~OSRWindow(); - - void Render(); - void EnableGL(); - void DisableGL(); - - ClientOSRenderer renderer_; - OSRBrowserProvider* browser_provider_; - CefWindowHandle glarea_; - bool gl_enabled_; - - bool painting_popup_; - bool render_task_pending_; - - IMPLEMENT_REFCOUNTING(OSRWindow); -}; - -#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_ +// Copyright (c) 2013 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 CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_ +#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_ +#pragma once + +#include "include/cef_render_handler.h" +#include "cefclient/client_handler.h" +#include "cefclient/osrenderer.h" + +class OSRBrowserProvider { + public: + virtual CefRefPtr GetBrowser() =0; + + protected: + virtual ~OSRBrowserProvider() {} +}; + +class OSRWindow : public ClientHandler::RenderHandler { + public: + // Create a new OSRWindow instance. |browser_provider| must outlive this + // object. + static CefRefPtr Create(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView); + + static CefRefPtr From( + CefRefPtr renderHandler); + + CefWindowHandle GetWindowHandle() const { + return glarea_; + } + CefRefPtr GetBrowserHost() const { + return browser_provider_->GetBrowser()->GetHost(); + } + + // ClientHandler::RenderHandler methods + virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; + + // CefRenderHandler methods + virtual bool GetViewRect(CefRefPtr browser, + CefRect& rect) OVERRIDE; + virtual bool GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) OVERRIDE; + virtual void OnPopupShow(CefRefPtr browser, + bool show) OVERRIDE; + virtual void OnPopupSize(CefRefPtr browser, + const CefRect& rect) OVERRIDE; + virtual void OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer, + int width, + int height) OVERRIDE; + virtual void OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) OVERRIDE; + + void Invalidate(); + bool IsOverPopupWidget(int x, int y) const; + int GetPopupXOffset() const; + int GetPopupYOffset() const; + void ApplyPopupOffset(int& x, int& y) const; + + private: + OSRWindow(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView); + virtual ~OSRWindow(); + + void Render(); + void EnableGL(); + void DisableGL(); + + ClientOSRenderer renderer_; + OSRBrowserProvider* browser_provider_; + CefWindowHandle glarea_; + bool gl_enabled_; + + bool painting_popup_; + bool render_task_pending_; + + IMPLEMENT_REFCOUNTING(OSRWindow); +}; + +#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_GTK_H_ diff --git a/tests/cefclient/cefclient_osr_widget_mac.h b/tests/cefclient/cefclient_osr_widget_mac.h index 6e9c0c6a6..ea0716aca 100644 --- a/tests/cefclient/cefclient_osr_widget_mac.h +++ b/tests/cefclient/cefclient_osr_widget_mac.h @@ -1,128 +1,128 @@ -// Copyright (c) 2013 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 CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_ -#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_ - -#include "include/cef_client.h" -#include "cefclient/client_handler.h" - -class ClientOSRenderer; - -class OSRBrowserProvider { - public: - virtual CefRefPtr GetBrowser() =0; - - protected: - virtual ~OSRBrowserProvider() {} -}; - -// The client OpenGL view. -@interface ClientOpenGLView : NSOpenGLView { -@public - NSTrackingArea* tracking_area_; - OSRBrowserProvider* browser_provider_; - ClientOSRenderer* renderer_; - NSPoint last_mouse_pos_; - NSPoint cur_mouse_pos_; - bool rotating_; - - bool was_last_mouse_down_on_view_; - - // Event monitor for scroll wheel end event. - id endWheelMonitor_; -} - -- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency; -- (NSPoint)getClickPointForEvent:(NSEvent*)event; -- (void)getKeyEvent:(CefKeyEvent&)keyEvent forEvent:(NSEvent*)event; -- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event; -- (int)getModifiersForEvent:(NSEvent*)event; -- (BOOL)isKeyUpEvent:(NSEvent*)event; -- (BOOL)isKeyPadEvent:(NSEvent*)event; -- (CefRefPtr)getBrowser; -@end - -// Handler for off-screen rendering windows. -class ClientOSRHandler : public ClientHandler::RenderHandler { - public: - explicit ClientOSRHandler(ClientOpenGLView* view, - OSRBrowserProvider* browser_provider); - virtual ~ClientOSRHandler(); - - void Disconnect(); - - // ClientHandler::RenderHandler - virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; - - // CefRenderHandler methods - - virtual bool GetViewRect(CefRefPtr browser, - CefRect& rect) OVERRIDE; - - virtual bool GetScreenPoint(CefRefPtr browser, - int viewX, - int viewY, - int& screenX, - int& screenY) OVERRIDE; - virtual bool GetScreenInfo(CefRefPtr browser, - CefScreenInfo& screen_info) OVERRIDE; - - virtual void OnPopupShow(CefRefPtr browser, - bool show) OVERRIDE; - - virtual void OnPopupSize(CefRefPtr browser, - const CefRect& rect) OVERRIDE; - - virtual void OnPaint(CefRefPtr browser, - PaintElementType type, - const RectList& dirtyRects, - const void* buffer, - int width, int height) OVERRIDE; - - virtual void OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) OVERRIDE; - - CefWindowHandle view() { return view_; } - - private: - void SetLoading(bool isLoading); - - ClientOpenGLView* view_; - - bool painting_popup_; - - // Include the default reference counting implementation. - IMPLEMENT_REFCOUNTING(ClientOSRHandler); -}; - -class OSRWindow { - public: - static CefRefPtr Create(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView, - const CefRect& frame); - - CefRefPtr GetRenderHandler() { - return render_client.get(); - } - - CefWindowHandle GetWindowHandle() { return view_; } - - private: - OSRWindow(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView, - const CefRect& frame); - - ~OSRWindow(); - - CefRefPtr render_client; - CefWindowHandle view_; - - IMPLEMENT_REFCOUNTING(OSRWindow); -}; - -#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_ - +// Copyright (c) 2013 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 CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_ +#define CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_ + +#include "include/cef_client.h" +#include "cefclient/client_handler.h" + +class ClientOSRenderer; + +class OSRBrowserProvider { + public: + virtual CefRefPtr GetBrowser() =0; + + protected: + virtual ~OSRBrowserProvider() {} +}; + +// The client OpenGL view. +@interface ClientOpenGLView : NSOpenGLView { +@public + NSTrackingArea* tracking_area_; + OSRBrowserProvider* browser_provider_; + ClientOSRenderer* renderer_; + NSPoint last_mouse_pos_; + NSPoint cur_mouse_pos_; + bool rotating_; + + bool was_last_mouse_down_on_view_; + + // Event monitor for scroll wheel end event. + id endWheelMonitor_; +} + +- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency; +- (NSPoint)getClickPointForEvent:(NSEvent*)event; +- (void)getKeyEvent:(CefKeyEvent&)keyEvent forEvent:(NSEvent*)event; +- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event; +- (int)getModifiersForEvent:(NSEvent*)event; +- (BOOL)isKeyUpEvent:(NSEvent*)event; +- (BOOL)isKeyPadEvent:(NSEvent*)event; +- (CefRefPtr)getBrowser; +@end + +// Handler for off-screen rendering windows. +class ClientOSRHandler : public ClientHandler::RenderHandler { + public: + explicit ClientOSRHandler(ClientOpenGLView* view, + OSRBrowserProvider* browser_provider); + virtual ~ClientOSRHandler(); + + void Disconnect(); + + // ClientHandler::RenderHandler + virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; + + // CefRenderHandler methods + + virtual bool GetViewRect(CefRefPtr browser, + CefRect& rect) OVERRIDE; + + virtual bool GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) OVERRIDE; + virtual bool GetScreenInfo(CefRefPtr browser, + CefScreenInfo& screen_info) OVERRIDE; + + virtual void OnPopupShow(CefRefPtr browser, + bool show) OVERRIDE; + + virtual void OnPopupSize(CefRefPtr browser, + const CefRect& rect) OVERRIDE; + + virtual void OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer, + int width, int height) OVERRIDE; + + virtual void OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) OVERRIDE; + + CefWindowHandle view() { return view_; } + + private: + void SetLoading(bool isLoading); + + ClientOpenGLView* view_; + + bool painting_popup_; + + // Include the default reference counting implementation. + IMPLEMENT_REFCOUNTING(ClientOSRHandler); +}; + +class OSRWindow { + public: + static CefRefPtr Create(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView, + const CefRect& frame); + + CefRefPtr GetRenderHandler() { + return render_client.get(); + } + + CefWindowHandle GetWindowHandle() { return view_; } + + private: + OSRWindow(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView, + const CefRect& frame); + + ~OSRWindow(); + + CefRefPtr render_client; + CefWindowHandle view_; + + IMPLEMENT_REFCOUNTING(OSRWindow); +}; + +#endif // CEF_TESTS_CEFCLIENT_CEFCLIENT_OSR_WIDGET_MAC_H_ + diff --git a/tests/cefclient/cefclient_osr_widget_mac.mm b/tests/cefclient/cefclient_osr_widget_mac.mm index 2f9e9fafd..61ad9f5c2 100644 --- a/tests/cefclient/cefclient_osr_widget_mac.mm +++ b/tests/cefclient/cefclient_osr_widget_mac.mm @@ -1,930 +1,930 @@ -// Copyright (c) 2013 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. - -#import -#import -#include - -#include "cefclient/cefclient_osr_widget_mac.h" - -#include "include/cef_application_mac.h" -#include "include/cef_browser.h" -#include "include/cef_client.h" -#include "cefclient/cefclient.h" -#include "cefclient/osrenderer.h" -#include "cefclient/resource_util.h" -#include "cefclient/util.h" - -// This method will return YES for OS X versions 10.7.3 and later, and NO -// otherwise. -// Used to prevent a crash when building with the 10.7 SDK and accessing the -// notification below. See: http://crbug.com/260595. -static BOOL SupportsBackingPropertiesChangedNotification() { - // windowDidChangeBackingProperties: method has been added to the - // NSWindowDelegate protocol in 10.7.3, at the same time as the - // NSWindowDidChangeBackingPropertiesNotification notification was added. - // If the protocol contains this method description, the notification should - // be supported as well. - Protocol* windowDelegateProtocol = NSProtocolFromString(@"NSWindowDelegate"); - struct objc_method_description methodDescription = - protocol_getMethodDescription( - windowDelegateProtocol, - @selector(windowDidChangeBackingProperties:), - NO, - YES); - - // If the protocol does not contain the method, the returned method - // description is {NULL, NULL} - return methodDescription.name != NULL || methodDescription.types != NULL; -} - -@interface ClientOpenGLView () -- (float)getDeviceScaleFactor; -- (void)windowDidChangeBackingProperties:(NSNotification*)notification; - -- (bool) isOverPopupWidgetX: (int) x andY: (int) y; -- (void) applyPopupOffsetToX: (int&) x andY: (int&) y; -- (int) getPopupXOffset; -- (int) getPopupYOffset; - -- (void) sendMouseClick: (NSEvent *)event - button: (CefBrowserHost::MouseButtonType)type - isUp: (bool)isUp; - -- (void) convertRects: (const CefRenderHandler::RectList&) rects - toBackingRects: (CefRenderHandler::RectList*) scaled_rects - andSize: (const NSSize) size - toBackingSize: (NSSize*) scaled_size; - -- (CefRect) convertRectToBackingInternal: (const CefRect&) rect; -- (CefRect) convertRectFromBackingInternal: (const CefRect&) rect; - -@property (readwrite, atomic) bool was_last_mouse_down_on_view; -@end - -namespace { - -static CefRect convertRect(const NSRect& target, const NSRect& frame) { - NSRect rect = target; - rect.origin.y = NSMaxY(frame) - NSMaxY(target); - return CefRect(rect.origin.x, - rect.origin.y, - rect.size.width, - rect.size.height); -} - -} // namespace - -ClientOSRHandler::ClientOSRHandler(ClientOpenGLView* view, - OSRBrowserProvider* browser_provider) - : view_(view), - painting_popup_(false) { - [view_ retain]; - view_->browser_provider_ = browser_provider; - - // Backing property notifications crash on 10.6 when building with the 10.7 - // SDK, see http://crbug.com/260595. - static BOOL supportsBackingPropertiesNotification = - SupportsBackingPropertiesChangedNotification(); - if (supportsBackingPropertiesNotification) { - [[NSNotificationCenter defaultCenter] - addObserver:view_ - selector:@selector(windowDidChangeBackingProperties:) - name:NSWindowDidChangeBackingPropertiesNotification - object:[view_ window]]; - } -} - -ClientOSRHandler:: ~ClientOSRHandler() { - static BOOL supportsBackingPropertiesNotification = - SupportsBackingPropertiesChangedNotification(); - - if (supportsBackingPropertiesNotification) { - [[NSNotificationCenter defaultCenter] - removeObserver:view_ - name:NSWindowDidChangeBackingPropertiesNotification - object:[view_ window]]; - } -} - -void ClientOSRHandler::Disconnect() { - [view_ release]; - view_ = nil; -} - -// CefRenderHandler methods -void ClientOSRHandler::OnBeforeClose(CefRefPtr browser) { - if (view_) - view_->browser_provider_ = NULL; -} - -bool ClientOSRHandler::GetViewRect(CefRefPtr browser, - CefRect& rect) { - REQUIRE_UI_THREAD(); - - if (!view_) - return false; - - // The simulated screen and view rectangle are the same. This is necessary - // for popup menus to be located and sized inside the view. - const NSRect bounds = [view_ bounds]; - rect.x = rect.y = 0; - rect.width = bounds.size.width; - rect.height = bounds.size.height; - return true; -} - -bool ClientOSRHandler::GetScreenPoint(CefRefPtr browser, - int viewX, - int viewY, - int& screenX, - int& screenY) { - REQUIRE_UI_THREAD(); - - if (!view_) - return false; - - // Convert the point from view coordinates to actual screen coordinates. - NSRect bounds = [view_ bounds]; - NSPoint view_pt = NSMakePoint(viewX, bounds.size.height - viewY); - NSPoint window_pt = [view_ convertPoint:view_pt toView:nil]; - NSPoint screen_pt = [[view_ window] convertBaseToScreen:window_pt]; - screenX = screen_pt.x; - screenY = screen_pt.y; - return true; -} - -bool ClientOSRHandler::GetScreenInfo(CefRefPtr browser, - CefScreenInfo& screen_info) { - REQUIRE_UI_THREAD(); - - if (!view_) - return false; - - NSWindow* window = [view_ window]; - if (!window) - return false; - - screen_info.device_scale_factor = [view_ getDeviceScaleFactor]; - - NSScreen* screen = [window screen]; - if (!screen) - screen = [NSScreen deepestScreen]; - - screen_info.depth = NSBitsPerPixelFromDepth([screen depth]); - screen_info.depth_per_component = NSBitsPerSampleFromDepth([screen depth]); - screen_info.is_monochrome = - [[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel; - // screen_info.is_monochrome = true; - screen_info.rect = convertRect([screen frame], [screen frame]); - screen_info.available_rect = - convertRect([screen visibleFrame], [screen frame]); - - return true; -} - -void ClientOSRHandler::OnPopupShow(CefRefPtr browser, - bool show) { - REQUIRE_UI_THREAD(); - - if (!view_) - return; - - if (!show) { - CefRect client_popup_rect = view_->renderer_->popup_rect(); - - // Clear the popup rectangles, so that the paint triggered by Invalidate - // will not repaint the popup content over the OpenGL view. - view_->renderer_->ClearPopupRects(); - CefRect scaled_rect = - [view_ convertRectFromBackingInternal:client_popup_rect]; - browser->GetHost()->Invalidate(scaled_rect, PET_VIEW); - } - - view_->renderer_->OnPopupShow(browser, show); -} - -void ClientOSRHandler::OnPopupSize(CefRefPtr browser, - const CefRect& rect) { - REQUIRE_UI_THREAD(); - - if (!view_) - return; - - CefRect scaled_rect = [view_ convertRectToBackingInternal:rect]; - view_->renderer_->OnPopupSize(browser, scaled_rect); -} - -void ClientOSRHandler::OnPaint(CefRefPtr browser, - PaintElementType type, - const RectList& dirtyRects, - const void* buffer, - int width, int height) { - REQUIRE_UI_THREAD(); - - if (!view_) - return; - - if (painting_popup_) { - RectList scaled_dirty_rects; - NSSize scaled_size = NSMakeSize(0, 0); - [view_ convertRects:dirtyRects - toBackingRects:&scaled_dirty_rects - andSize:NSMakeSize(width, height) - toBackingSize:&scaled_size]; - view_->renderer_->OnPaint(browser, type, scaled_dirty_rects, buffer, - scaled_size.width, scaled_size.height); - return; - } - - NSOpenGLContext* context = [view_ openGLContext]; - [context makeCurrentContext]; - - RectList scaled_dirty_rects; - NSSize scaled_size = NSMakeSize(0, 0); - [view_ convertRects:dirtyRects - toBackingRects:&scaled_dirty_rects - andSize:NSMakeSize(width, height) - toBackingSize:&scaled_size]; - - view_->renderer_->OnPaint(browser, type, scaled_dirty_rects, buffer, - scaled_size.width, scaled_size.height); - - if (type == PET_VIEW && !view_->renderer_->popup_rect().IsEmpty()) { - painting_popup_ = true; - CefRect client_popup_rect(0, 0, - view_->renderer_->popup_rect().width, - view_->renderer_->popup_rect().height); - - CefRect scaled_popup_rect = - [view_ convertRectFromBackingInternal:client_popup_rect]; - - browser->GetHost()->Invalidate(scaled_popup_rect, PET_POPUP); - painting_popup_ = false; - } - - view_->renderer_->Render(); - [context flushBuffer]; -} - -void ClientOSRHandler::OnCursorChange(CefRefPtr browser, - CefCursorHandle cursor) { - REQUIRE_UI_THREAD(); - [cursor set]; -} - -void ClientOSRHandler::SetLoading(bool isLoading) { -} - -@implementation ClientOpenGLView - -@synthesize was_last_mouse_down_on_view = was_last_mouse_down_on_view_; - -- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency { - NSOpenGLPixelFormat * pixelFormat = - [[NSOpenGLPixelFormat alloc] - initWithAttributes:(NSOpenGLPixelFormatAttribute[]) { - NSOpenGLPFAWindow, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFADepthSize, - 32, - 0}]; - [pixelFormat autorelease]; - - self = [super initWithFrame:frame pixelFormat:pixelFormat]; - if (self) { - renderer_ = new ClientOSRenderer(transparency); - rotating_ = false; - endWheelMonitor_ = nil; - - tracking_area_ = - [[NSTrackingArea alloc] initWithRect:frame - options:NSTrackingMouseMoved | - NSTrackingActiveInActiveApp | - NSTrackingInVisibleRect - owner:self - userInfo:nil]; - [self addTrackingArea:tracking_area_]; - } - - if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { - // enable HiDPI buffer - [self setWantsBestResolutionOpenGLSurface:YES]; - } - - return self; -} - -- (void)dealloc { - CefRefPtr browser = [self getBrowser]; - if (browser) { - static_cast( - browser->GetHost()->GetClient()->GetRenderHandler().get())->Disconnect(); - browser->GetHost()->CloseBrowser(true); - browser = NULL; - } - if (renderer_) - delete renderer_; - - [super dealloc]; -} - -- (CefRefPtr)getBrowser { - if (browser_provider_) - return browser_provider_->GetBrowser(); - return NULL; -} - -- (void)setFrame:(NSRect)frameRect { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - [super setFrame:frameRect]; - browser->GetHost()->WasResized(); -} - -- (void) sendMouseClick:(NSEvent *)event - button: (CefBrowserHost::MouseButtonType)type - isUp: (bool)isUp { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; - NSPoint point = [self getClickPointForEvent:event]; - if (!isUp) - self.was_last_mouse_down_on_view = ![self isOverPopupWidgetX: point.x - andY: point.y]; - else if (self.was_last_mouse_down_on_view && - [self isOverPopupWidgetX:point.x andY: point.y] && - ([self getPopupXOffset] || [self getPopupYOffset])) { - return; - } - - browser->GetHost()->SendMouseClickEvent(mouseEvent, - type, - isUp, - [event clickCount]); -} - -- (void)mouseDown:(NSEvent *)event { - [self sendMouseClick: event button:MBT_LEFT isUp:false]; -} - -- (void)rightMouseDown:(NSEvent *)event { - if ([event modifierFlags] & NSShiftKeyMask) { - // Start rotation effect. - last_mouse_pos_ = cur_mouse_pos_ = [self getClickPointForEvent:event]; - rotating_ = true; - return; - } - - [self sendMouseClick: event button:MBT_RIGHT isUp:false]; -} - -- (void)otherMouseDown:(NSEvent *)event { - [self sendMouseClick: event button:MBT_MIDDLE isUp:false]; -} - -- (void)mouseUp:(NSEvent *)event { - [self sendMouseClick: event button: MBT_LEFT isUp: true]; -} - -- (void)rightMouseUp:(NSEvent *)event { - if (rotating_) { - // End rotation effect. - renderer_->SetSpin(0, 0); - rotating_ = false; - [self setNeedsDisplay:YES]; - return; - } - [self sendMouseClick: event button: MBT_RIGHT isUp: true]; -} - -- (void)otherMouseUp:(NSEvent *)event { - [self sendMouseClick: event button: MBT_MIDDLE isUp: true]; -} - -- (void)mouseMoved:(NSEvent *)event { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - if (rotating_) { - // Apply rotation effect. - cur_mouse_pos_ = [self getClickPointForEvent:event];; - renderer_->IncrementSpin((cur_mouse_pos_.x - last_mouse_pos_.x), - (cur_mouse_pos_.y - last_mouse_pos_.y)); - last_mouse_pos_ = cur_mouse_pos_; - [self setNeedsDisplay:YES]; - return; - } - - CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; - browser->GetHost()->SendMouseMoveEvent(mouseEvent, false); -} - -- (void)mouseDragged:(NSEvent *)event { - [self mouseMoved:event]; -} - -- (void)rightMouseDragged:(NSEvent *)event { - [self mouseMoved:event]; -} - -- (void)otherMouseDragged:(NSEvent *)event { - [self mouseMoved:event]; -} - -- (void)mouseEntered:(NSEvent *)event { - [self mouseMoved:event]; -} - -- (void)mouseExited:(NSEvent *)event { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; - browser->GetHost()->SendMouseMoveEvent(mouseEvent, true); -} - -- (void)keyDown:(NSEvent *)event { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - if ([event type] != NSFlagsChanged) { - browser->GetHost()->HandleKeyEventBeforeTextInputClient(event); - - // The return value of this method seems to always be set to YES, - // thus we ignore it and ask the host view whether IME is active - // or not. - [[self inputContext] handleEvent:event]; - - browser->GetHost()->HandleKeyEventAfterTextInputClient(event); - } -} - -- (void)keyUp:(NSEvent *)event { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - CefKeyEvent keyEvent; - [self getKeyEvent:keyEvent forEvent:event]; - - keyEvent.type = KEYEVENT_KEYUP; - browser->GetHost()->SendKeyEvent(keyEvent); -} - -- (void)flagsChanged:(NSEvent *)event { - if ([self isKeyUpEvent:event]) - [self keyUp:event]; - else - [self keyDown:event]; -} - -- (void)shortCircuitScrollWheelEvent:(NSEvent*)event { - // Phase is only supported in OS-X 10.7 and newer. - if ([event phase] != NSEventPhaseEnded && - [event phase] != NSEventPhaseCancelled) - return; - - [self sendScrollWheelEvet:event]; - - if (endWheelMonitor_) { - [NSEvent removeMonitor:endWheelMonitor_]; - endWheelMonitor_ = nil; - } -} - -- (void)scrollWheel:(NSEvent *)event { - // Phase is only supported in OS-X 10.7 and newer. - // Use an NSEvent monitor to listen for the wheel-end end. This ensures that - // the event is received even when the mouse cursor is no longer over the - // view when the scrolling ends. Also it avoids sending duplicate scroll - // events to the renderer. - if ([event respondsToSelector:@selector(phase)] && - [event phase] == NSEventPhaseBegan && !endWheelMonitor_) { - endWheelMonitor_ = - [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask - handler:^(NSEvent* blockEvent) { - [self shortCircuitScrollWheelEvent:blockEvent]; - return blockEvent; - }]; - } - - [self sendScrollWheelEvet:event]; -} - -- (void)sendScrollWheelEvet:(NSEvent *)event { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - CGEventRef cgEvent = [event CGEvent]; - ASSERT(cgEvent); - - int deltaX = - CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2); - int deltaY = - CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); - - CefMouseEvent mouseEvent; - [self getMouseEvent: mouseEvent forEvent: event]; - browser->GetHost()->SendMouseWheelEvent(mouseEvent, deltaX, deltaY); -} - -- (BOOL)canBecomeKeyView { - CefRefPtr browser = [self getBrowser]; - return (browser != NULL); -} - -- (BOOL)acceptsFirstResponder { - CefRefPtr browser = [self getBrowser]; - return (browser != NULL); -} - -- (BOOL)becomeFirstResponder { - CefRefPtr browser = [self getBrowser]; - if (browser) { - browser->GetHost()->SendFocusEvent(true); - return [super becomeFirstResponder]; - } - - return NO; -} - -- (BOOL)resignFirstResponder { - CefRefPtr browser = [self getBrowser]; - if (browser) { - browser->GetHost()->SendFocusEvent(false); - return [super resignFirstResponder]; - } - - return NO; -} - -- (void)undo:(id)sender { - CefRefPtr browser = [self getBrowser]; - if (browser) - browser->GetFocusedFrame()->Undo(); -} - -- (void)redo:(id)sender { - CefRefPtr browser = [self getBrowser]; - if (browser) - browser->GetFocusedFrame()->Redo(); -} - -- (void)cut:(id)sender { - CefRefPtr browser = [self getBrowser]; - if (browser) - browser->GetFocusedFrame()->Cut(); -} - -- (void)copy:(id)sender { - CefRefPtr browser = [self getBrowser]; - if (browser) - browser->GetFocusedFrame()->Copy(); -} - -- (void)paste:(id)sender { - CefRefPtr browser = [self getBrowser]; - if (browser) - browser->GetFocusedFrame()->Paste(); -} - -- (void)delete:(id)sender { - CefRefPtr browser = [self getBrowser]; - if (browser) - browser->GetFocusedFrame()->Delete(); -} - -- (void)selectAll:(id)sender { - CefRefPtr browser = [self getBrowser]; - if (browser) - browser->GetFocusedFrame()->SelectAll(); -} - -- (NSPoint)getClickPointForEvent:(NSEvent*)event { - NSPoint windowLocal = [event locationInWindow]; - NSPoint contentLocal = [self convertPoint:windowLocal fromView:nil]; - - NSPoint point; - point.x = contentLocal.x; - point.y = [self frame].size.height - contentLocal.y; // Flip y. - return point; -} - -- (void)getKeyEvent:(CefKeyEvent &)keyEvent forEvent:(NSEvent *)event { - if ([event type] == NSKeyDown || [event type] == NSKeyUp) { - NSString* s = [event characters]; - if ([s length] > 0) - keyEvent.character = [s characterAtIndex:0]; - - s = [event charactersIgnoringModifiers]; - if ([s length] > 0) - keyEvent.unmodified_character = [s characterAtIndex:0]; - } - - if ([event type] == NSFlagsChanged) { - keyEvent.character = 0; - keyEvent.unmodified_character = 0; - } - - keyEvent.native_key_code = [event keyCode]; - - keyEvent.modifiers = [self getModifiersForEvent:event]; -} - -- (NSTextInputContext*)inputContext { - CefRefPtr browser = [self getBrowser]; - if (browser) - return browser->GetHost()->GetNSTextInputContext(); - return NULL; -} - -- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event { - NSPoint point = [self getClickPointForEvent:event]; - mouseEvent.x = point.x; - mouseEvent.y = point.y; - - if ([self isOverPopupWidgetX:mouseEvent.x andY: mouseEvent.y]) { - [self applyPopupOffsetToX:mouseEvent.x andY: mouseEvent.y]; - } - - mouseEvent.modifiers = [self getModifiersForEvent:event]; -} - -- (int)getModifiersForEvent:(NSEvent*)event { - int modifiers = 0; - - if ([event modifierFlags] & NSControlKeyMask) - modifiers |= EVENTFLAG_CONTROL_DOWN; - if ([event modifierFlags] & NSShiftKeyMask) - modifiers |= EVENTFLAG_SHIFT_DOWN; - if ([event modifierFlags] & NSAlternateKeyMask) - modifiers |= EVENTFLAG_ALT_DOWN; - if ([event modifierFlags] & NSCommandKeyMask) - modifiers |= EVENTFLAG_COMMAND_DOWN; - if ([event modifierFlags] & NSAlphaShiftKeyMask) - modifiers |= EVENTFLAG_CAPS_LOCK_ON; - - if ([event type] == NSKeyUp || - [event type] == NSKeyDown || - [event type] == NSFlagsChanged) { - // Only perform this check for key events - if ([self isKeyPadEvent:event]) - modifiers |= EVENTFLAG_IS_KEY_PAD; - } - - // OS X does not have a modifier for NumLock, so I'm not entirely sure how to - // set EVENTFLAG_NUM_LOCK_ON; - // - // There is no EVENTFLAG for the function key either. - - // Mouse buttons - switch ([event type]) { - case NSLeftMouseDragged: - case NSLeftMouseDown: - case NSLeftMouseUp: - modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; - break; - case NSRightMouseDragged: - case NSRightMouseDown: - case NSRightMouseUp: - modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; - break; - case NSOtherMouseDragged: - case NSOtherMouseDown: - case NSOtherMouseUp: - modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; - break; - } - - return modifiers; -} - -- (BOOL)isKeyUpEvent:(NSEvent*)event { - if ([event type] != NSFlagsChanged) - return [event type] == NSKeyUp; - - // FIXME: This logic fails if the user presses both Shift keys at once, for - // example: we treat releasing one of them as keyDown. - switch ([event keyCode]) { - case 54: // Right Command - case 55: // Left Command - return ([event modifierFlags] & NSCommandKeyMask) == 0; - - case 57: // Capslock - return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0; - - case 56: // Left Shift - case 60: // Right Shift - return ([event modifierFlags] & NSShiftKeyMask) == 0; - - case 58: // Left Alt - case 61: // Right Alt - return ([event modifierFlags] & NSAlternateKeyMask) == 0; - - case 59: // Left Ctrl - case 62: // Right Ctrl - return ([event modifierFlags] & NSControlKeyMask) == 0; - - case 63: // Function - return ([event modifierFlags] & NSFunctionKeyMask) == 0; - } - return false; -} - -- (BOOL)isKeyPadEvent:(NSEvent*)event { - if ([event modifierFlags] & NSNumericPadKeyMask) - return true; - - switch ([event keyCode]) { - case 71: // Clear - case 81: // = - case 75: // / - case 67: // * - case 78: // - - case 69: // + - case 76: // Enter - case 65: // . - case 82: // 0 - case 83: // 1 - case 84: // 2 - case 85: // 3 - case 86: // 4 - case 87: // 5 - case 88: // 6 - case 89: // 7 - case 91: // 8 - case 92: // 9 - return true; - } - - return false; -} - -- (void)windowDidChangeBackingProperties:(NSNotification*)notification { - // This delegate method is only called on 10.7 and later, so don't worry about - // other backing changes calling it on 10.6 or earlier - CGFloat newBackingScaleFactor = [self getDeviceScaleFactor]; - NSNumber* oldBackingScaleFactor = - [[notification userInfo] objectForKey:NSBackingPropertyOldScaleFactorKey]; - if (newBackingScaleFactor != [oldBackingScaleFactor doubleValue]) { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - browser->GetHost()->NotifyScreenInfoChanged(); - } -} - -- (void)drawRect: (NSRect) dirtyRect { - // The Invalidate below fixes flicker when resizing - if ([self inLiveResize]) { - CefRefPtr browser = [self getBrowser]; - if (!browser) - return; - - NSRect b = [self bounds]; - CefRect boundsRect = CefRect((int)b.origin.x, - (int)b.origin.y, - (int)b.size.width, - (int)b.size.height); - browser->GetHost()->Invalidate(boundsRect, PET_VIEW); - } -} - -// Utility - private -- (float)getDeviceScaleFactor { - float deviceScaleFactor = 1; - NSWindow* window = [self window]; - if (!window) - return deviceScaleFactor; - - if ([window respondsToSelector:@selector(backingScaleFactor)]) - deviceScaleFactor = [window backingScaleFactor]; - else - deviceScaleFactor = [window userSpaceScaleFactor]; - - return deviceScaleFactor; -} - -- (bool) isOverPopupWidgetX: (int) x andY: (int) y { - CefRect rc = [self convertRectFromBackingInternal:renderer_->popup_rect()]; - int popup_right = rc.x + rc.width; - int popup_bottom = rc.y + rc.height; - return (x >= rc.x) && (x < popup_right) && - (y >= rc.y) && (y < popup_bottom); -} - -- (int) getPopupXOffset { - int original_x = - [self convertRectFromBackingInternal:renderer_->original_popup_rect()].x; - int popup_x = - [self convertRectFromBackingInternal:renderer_->popup_rect()].x; - - return original_x - popup_x; -} - -- (int) getPopupYOffset { - int original_y = - [self convertRectFromBackingInternal:renderer_->original_popup_rect()].y; - int popup_y = - [self convertRectFromBackingInternal:renderer_->popup_rect()].y; - - return original_y - popup_y; -} - -- (void) applyPopupOffsetToX: (int&) x andY: (int&) y { - if ([self isOverPopupWidgetX:x andY:y]) { - x += [self getPopupXOffset]; - y += [self getPopupYOffset]; - } -} - -- (void) convertRects: (const CefRenderHandler::RectList&) rects - toBackingRects: (CefRenderHandler::RectList*) scaled_rects - andSize: (const NSSize) size - toBackingSize: (NSSize*) scaled_size { - *scaled_rects = rects; - *scaled_size = size; - - if ([self getDeviceScaleFactor] != 1 && - [self respondsToSelector:@selector(convertSizeToBacking:)] && - [self respondsToSelector:@selector(convertRectToBacking:)]) { - CefRenderHandler::RectList scaled_dirty_rects; - for (size_t i = 0; i < rects.size(); ++i) { - scaled_dirty_rects.push_back([self convertRectToBackingInternal:rects[i]]); - } - - *scaled_rects = scaled_dirty_rects; - *scaled_size = [self convertSizeToBacking:size]; - } -} - -- (CefRect) convertRectToBackingInternal: (const CefRect&) rect { - if ([self getDeviceScaleFactor] == 1) - return rect; - - if ([self respondsToSelector:@selector(convertRectToBacking:)]) { - NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); - NSRect scaled_rect = [self convertRectToBacking:old_rect]; - return CefRect((int)scaled_rect.origin.x, - (int)scaled_rect.origin.y, - (int)scaled_rect.size.width, - (int)scaled_rect.size.height); - } - - return rect; -} - -- (CefRect) convertRectFromBackingInternal: (const CefRect&) rect { - if ([self respondsToSelector:@selector(convertRectFromBacking:)]) { - NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); - NSRect scaled_rect = [self convertRectFromBacking:old_rect]; - return CefRect((int)scaled_rect.origin.x, - (int)scaled_rect.origin.y, - (int)scaled_rect.size.width, - (int)scaled_rect.size.height); - } - - return rect; -} - -@end - - -CefRefPtr OSRWindow::Create(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView, - const CefRect& frame) { - return new OSRWindow(browser_provider, transparent, parentView, frame); -} - -OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, - bool transparent, - CefWindowHandle parentView, - const CefRect& frame) { - NSRect window_rect = NSMakeRect(frame.x, frame.y, frame.width, frame.height); - ClientOpenGLView* view = [[ClientOpenGLView alloc] initWithFrame:window_rect - andTransparency:transparent]; - this->view_ = view; - [parentView addSubview:view]; - [view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [view setAutoresizesSubviews: true]; - - this->render_client = new ClientOSRHandler(view, browser_provider); -} - -OSRWindow::~OSRWindow() { -} +// Copyright (c) 2013 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. + +#import +#import +#include + +#include "cefclient/cefclient_osr_widget_mac.h" + +#include "include/cef_application_mac.h" +#include "include/cef_browser.h" +#include "include/cef_client.h" +#include "cefclient/cefclient.h" +#include "cefclient/osrenderer.h" +#include "cefclient/resource_util.h" +#include "cefclient/util.h" + +// This method will return YES for OS X versions 10.7.3 and later, and NO +// otherwise. +// Used to prevent a crash when building with the 10.7 SDK and accessing the +// notification below. See: http://crbug.com/260595. +static BOOL SupportsBackingPropertiesChangedNotification() { + // windowDidChangeBackingProperties: method has been added to the + // NSWindowDelegate protocol in 10.7.3, at the same time as the + // NSWindowDidChangeBackingPropertiesNotification notification was added. + // If the protocol contains this method description, the notification should + // be supported as well. + Protocol* windowDelegateProtocol = NSProtocolFromString(@"NSWindowDelegate"); + struct objc_method_description methodDescription = + protocol_getMethodDescription( + windowDelegateProtocol, + @selector(windowDidChangeBackingProperties:), + NO, + YES); + + // If the protocol does not contain the method, the returned method + // description is {NULL, NULL} + return methodDescription.name != NULL || methodDescription.types != NULL; +} + +@interface ClientOpenGLView () +- (float)getDeviceScaleFactor; +- (void)windowDidChangeBackingProperties:(NSNotification*)notification; + +- (bool) isOverPopupWidgetX: (int) x andY: (int) y; +- (void) applyPopupOffsetToX: (int&) x andY: (int&) y; +- (int) getPopupXOffset; +- (int) getPopupYOffset; + +- (void) sendMouseClick: (NSEvent *)event + button: (CefBrowserHost::MouseButtonType)type + isUp: (bool)isUp; + +- (void) convertRects: (const CefRenderHandler::RectList&) rects + toBackingRects: (CefRenderHandler::RectList*) scaled_rects + andSize: (const NSSize) size + toBackingSize: (NSSize*) scaled_size; + +- (CefRect) convertRectToBackingInternal: (const CefRect&) rect; +- (CefRect) convertRectFromBackingInternal: (const CefRect&) rect; + +@property (readwrite, atomic) bool was_last_mouse_down_on_view; +@end + +namespace { + +static CefRect convertRect(const NSRect& target, const NSRect& frame) { + NSRect rect = target; + rect.origin.y = NSMaxY(frame) - NSMaxY(target); + return CefRect(rect.origin.x, + rect.origin.y, + rect.size.width, + rect.size.height); +} + +} // namespace + +ClientOSRHandler::ClientOSRHandler(ClientOpenGLView* view, + OSRBrowserProvider* browser_provider) + : view_(view), + painting_popup_(false) { + [view_ retain]; + view_->browser_provider_ = browser_provider; + + // Backing property notifications crash on 10.6 when building with the 10.7 + // SDK, see http://crbug.com/260595. + static BOOL supportsBackingPropertiesNotification = + SupportsBackingPropertiesChangedNotification(); + if (supportsBackingPropertiesNotification) { + [[NSNotificationCenter defaultCenter] + addObserver:view_ + selector:@selector(windowDidChangeBackingProperties:) + name:NSWindowDidChangeBackingPropertiesNotification + object:[view_ window]]; + } +} + +ClientOSRHandler:: ~ClientOSRHandler() { + static BOOL supportsBackingPropertiesNotification = + SupportsBackingPropertiesChangedNotification(); + + if (supportsBackingPropertiesNotification) { + [[NSNotificationCenter defaultCenter] + removeObserver:view_ + name:NSWindowDidChangeBackingPropertiesNotification + object:[view_ window]]; + } +} + +void ClientOSRHandler::Disconnect() { + [view_ release]; + view_ = nil; +} + +// CefRenderHandler methods +void ClientOSRHandler::OnBeforeClose(CefRefPtr browser) { + if (view_) + view_->browser_provider_ = NULL; +} + +bool ClientOSRHandler::GetViewRect(CefRefPtr browser, + CefRect& rect) { + REQUIRE_UI_THREAD(); + + if (!view_) + return false; + + // The simulated screen and view rectangle are the same. This is necessary + // for popup menus to be located and sized inside the view. + const NSRect bounds = [view_ bounds]; + rect.x = rect.y = 0; + rect.width = bounds.size.width; + rect.height = bounds.size.height; + return true; +} + +bool ClientOSRHandler::GetScreenPoint(CefRefPtr browser, + int viewX, + int viewY, + int& screenX, + int& screenY) { + REQUIRE_UI_THREAD(); + + if (!view_) + return false; + + // Convert the point from view coordinates to actual screen coordinates. + NSRect bounds = [view_ bounds]; + NSPoint view_pt = NSMakePoint(viewX, bounds.size.height - viewY); + NSPoint window_pt = [view_ convertPoint:view_pt toView:nil]; + NSPoint screen_pt = [[view_ window] convertBaseToScreen:window_pt]; + screenX = screen_pt.x; + screenY = screen_pt.y; + return true; +} + +bool ClientOSRHandler::GetScreenInfo(CefRefPtr browser, + CefScreenInfo& screen_info) { + REQUIRE_UI_THREAD(); + + if (!view_) + return false; + + NSWindow* window = [view_ window]; + if (!window) + return false; + + screen_info.device_scale_factor = [view_ getDeviceScaleFactor]; + + NSScreen* screen = [window screen]; + if (!screen) + screen = [NSScreen deepestScreen]; + + screen_info.depth = NSBitsPerPixelFromDepth([screen depth]); + screen_info.depth_per_component = NSBitsPerSampleFromDepth([screen depth]); + screen_info.is_monochrome = + [[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel; + // screen_info.is_monochrome = true; + screen_info.rect = convertRect([screen frame], [screen frame]); + screen_info.available_rect = + convertRect([screen visibleFrame], [screen frame]); + + return true; +} + +void ClientOSRHandler::OnPopupShow(CefRefPtr browser, + bool show) { + REQUIRE_UI_THREAD(); + + if (!view_) + return; + + if (!show) { + CefRect client_popup_rect = view_->renderer_->popup_rect(); + + // Clear the popup rectangles, so that the paint triggered by Invalidate + // will not repaint the popup content over the OpenGL view. + view_->renderer_->ClearPopupRects(); + CefRect scaled_rect = + [view_ convertRectFromBackingInternal:client_popup_rect]; + browser->GetHost()->Invalidate(scaled_rect, PET_VIEW); + } + + view_->renderer_->OnPopupShow(browser, show); +} + +void ClientOSRHandler::OnPopupSize(CefRefPtr browser, + const CefRect& rect) { + REQUIRE_UI_THREAD(); + + if (!view_) + return; + + CefRect scaled_rect = [view_ convertRectToBackingInternal:rect]; + view_->renderer_->OnPopupSize(browser, scaled_rect); +} + +void ClientOSRHandler::OnPaint(CefRefPtr browser, + PaintElementType type, + const RectList& dirtyRects, + const void* buffer, + int width, int height) { + REQUIRE_UI_THREAD(); + + if (!view_) + return; + + if (painting_popup_) { + RectList scaled_dirty_rects; + NSSize scaled_size = NSMakeSize(0, 0); + [view_ convertRects:dirtyRects + toBackingRects:&scaled_dirty_rects + andSize:NSMakeSize(width, height) + toBackingSize:&scaled_size]; + view_->renderer_->OnPaint(browser, type, scaled_dirty_rects, buffer, + scaled_size.width, scaled_size.height); + return; + } + + NSOpenGLContext* context = [view_ openGLContext]; + [context makeCurrentContext]; + + RectList scaled_dirty_rects; + NSSize scaled_size = NSMakeSize(0, 0); + [view_ convertRects:dirtyRects + toBackingRects:&scaled_dirty_rects + andSize:NSMakeSize(width, height) + toBackingSize:&scaled_size]; + + view_->renderer_->OnPaint(browser, type, scaled_dirty_rects, buffer, + scaled_size.width, scaled_size.height); + + if (type == PET_VIEW && !view_->renderer_->popup_rect().IsEmpty()) { + painting_popup_ = true; + CefRect client_popup_rect(0, 0, + view_->renderer_->popup_rect().width, + view_->renderer_->popup_rect().height); + + CefRect scaled_popup_rect = + [view_ convertRectFromBackingInternal:client_popup_rect]; + + browser->GetHost()->Invalidate(scaled_popup_rect, PET_POPUP); + painting_popup_ = false; + } + + view_->renderer_->Render(); + [context flushBuffer]; +} + +void ClientOSRHandler::OnCursorChange(CefRefPtr browser, + CefCursorHandle cursor) { + REQUIRE_UI_THREAD(); + [cursor set]; +} + +void ClientOSRHandler::SetLoading(bool isLoading) { +} + +@implementation ClientOpenGLView + +@synthesize was_last_mouse_down_on_view = was_last_mouse_down_on_view_; + +- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency { + NSOpenGLPixelFormat * pixelFormat = + [[NSOpenGLPixelFormat alloc] + initWithAttributes:(NSOpenGLPixelFormatAttribute[]) { + NSOpenGLPFAWindow, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFADepthSize, + 32, + 0}]; + [pixelFormat autorelease]; + + self = [super initWithFrame:frame pixelFormat:pixelFormat]; + if (self) { + renderer_ = new ClientOSRenderer(transparency); + rotating_ = false; + endWheelMonitor_ = nil; + + tracking_area_ = + [[NSTrackingArea alloc] initWithRect:frame + options:NSTrackingMouseMoved | + NSTrackingActiveInActiveApp | + NSTrackingInVisibleRect + owner:self + userInfo:nil]; + [self addTrackingArea:tracking_area_]; + } + + if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { + // enable HiDPI buffer + [self setWantsBestResolutionOpenGLSurface:YES]; + } + + return self; +} + +- (void)dealloc { + CefRefPtr browser = [self getBrowser]; + if (browser) { + static_cast( + browser->GetHost()->GetClient()->GetRenderHandler().get())->Disconnect(); + browser->GetHost()->CloseBrowser(true); + browser = NULL; + } + if (renderer_) + delete renderer_; + + [super dealloc]; +} + +- (CefRefPtr)getBrowser { + if (browser_provider_) + return browser_provider_->GetBrowser(); + return NULL; +} + +- (void)setFrame:(NSRect)frameRect { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + [super setFrame:frameRect]; + browser->GetHost()->WasResized(); +} + +- (void) sendMouseClick:(NSEvent *)event + button: (CefBrowserHost::MouseButtonType)type + isUp: (bool)isUp { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + CefMouseEvent mouseEvent; + [self getMouseEvent: mouseEvent forEvent: event]; + NSPoint point = [self getClickPointForEvent:event]; + if (!isUp) + self.was_last_mouse_down_on_view = ![self isOverPopupWidgetX: point.x + andY: point.y]; + else if (self.was_last_mouse_down_on_view && + [self isOverPopupWidgetX:point.x andY: point.y] && + ([self getPopupXOffset] || [self getPopupYOffset])) { + return; + } + + browser->GetHost()->SendMouseClickEvent(mouseEvent, + type, + isUp, + [event clickCount]); +} + +- (void)mouseDown:(NSEvent *)event { + [self sendMouseClick: event button:MBT_LEFT isUp:false]; +} + +- (void)rightMouseDown:(NSEvent *)event { + if ([event modifierFlags] & NSShiftKeyMask) { + // Start rotation effect. + last_mouse_pos_ = cur_mouse_pos_ = [self getClickPointForEvent:event]; + rotating_ = true; + return; + } + + [self sendMouseClick: event button:MBT_RIGHT isUp:false]; +} + +- (void)otherMouseDown:(NSEvent *)event { + [self sendMouseClick: event button:MBT_MIDDLE isUp:false]; +} + +- (void)mouseUp:(NSEvent *)event { + [self sendMouseClick: event button: MBT_LEFT isUp: true]; +} + +- (void)rightMouseUp:(NSEvent *)event { + if (rotating_) { + // End rotation effect. + renderer_->SetSpin(0, 0); + rotating_ = false; + [self setNeedsDisplay:YES]; + return; + } + [self sendMouseClick: event button: MBT_RIGHT isUp: true]; +} + +- (void)otherMouseUp:(NSEvent *)event { + [self sendMouseClick: event button: MBT_MIDDLE isUp: true]; +} + +- (void)mouseMoved:(NSEvent *)event { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + if (rotating_) { + // Apply rotation effect. + cur_mouse_pos_ = [self getClickPointForEvent:event];; + renderer_->IncrementSpin((cur_mouse_pos_.x - last_mouse_pos_.x), + (cur_mouse_pos_.y - last_mouse_pos_.y)); + last_mouse_pos_ = cur_mouse_pos_; + [self setNeedsDisplay:YES]; + return; + } + + CefMouseEvent mouseEvent; + [self getMouseEvent: mouseEvent forEvent: event]; + browser->GetHost()->SendMouseMoveEvent(mouseEvent, false); +} + +- (void)mouseDragged:(NSEvent *)event { + [self mouseMoved:event]; +} + +- (void)rightMouseDragged:(NSEvent *)event { + [self mouseMoved:event]; +} + +- (void)otherMouseDragged:(NSEvent *)event { + [self mouseMoved:event]; +} + +- (void)mouseEntered:(NSEvent *)event { + [self mouseMoved:event]; +} + +- (void)mouseExited:(NSEvent *)event { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + CefMouseEvent mouseEvent; + [self getMouseEvent: mouseEvent forEvent: event]; + browser->GetHost()->SendMouseMoveEvent(mouseEvent, true); +} + +- (void)keyDown:(NSEvent *)event { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + if ([event type] != NSFlagsChanged) { + browser->GetHost()->HandleKeyEventBeforeTextInputClient(event); + + // The return value of this method seems to always be set to YES, + // thus we ignore it and ask the host view whether IME is active + // or not. + [[self inputContext] handleEvent:event]; + + browser->GetHost()->HandleKeyEventAfterTextInputClient(event); + } +} + +- (void)keyUp:(NSEvent *)event { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + CefKeyEvent keyEvent; + [self getKeyEvent:keyEvent forEvent:event]; + + keyEvent.type = KEYEVENT_KEYUP; + browser->GetHost()->SendKeyEvent(keyEvent); +} + +- (void)flagsChanged:(NSEvent *)event { + if ([self isKeyUpEvent:event]) + [self keyUp:event]; + else + [self keyDown:event]; +} + +- (void)shortCircuitScrollWheelEvent:(NSEvent*)event { + // Phase is only supported in OS-X 10.7 and newer. + if ([event phase] != NSEventPhaseEnded && + [event phase] != NSEventPhaseCancelled) + return; + + [self sendScrollWheelEvet:event]; + + if (endWheelMonitor_) { + [NSEvent removeMonitor:endWheelMonitor_]; + endWheelMonitor_ = nil; + } +} + +- (void)scrollWheel:(NSEvent *)event { + // Phase is only supported in OS-X 10.7 and newer. + // Use an NSEvent monitor to listen for the wheel-end end. This ensures that + // the event is received even when the mouse cursor is no longer over the + // view when the scrolling ends. Also it avoids sending duplicate scroll + // events to the renderer. + if ([event respondsToSelector:@selector(phase)] && + [event phase] == NSEventPhaseBegan && !endWheelMonitor_) { + endWheelMonitor_ = + [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask + handler:^(NSEvent* blockEvent) { + [self shortCircuitScrollWheelEvent:blockEvent]; + return blockEvent; + }]; + } + + [self sendScrollWheelEvet:event]; +} + +- (void)sendScrollWheelEvet:(NSEvent *)event { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + CGEventRef cgEvent = [event CGEvent]; + ASSERT(cgEvent); + + int deltaX = + CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2); + int deltaY = + CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); + + CefMouseEvent mouseEvent; + [self getMouseEvent: mouseEvent forEvent: event]; + browser->GetHost()->SendMouseWheelEvent(mouseEvent, deltaX, deltaY); +} + +- (BOOL)canBecomeKeyView { + CefRefPtr browser = [self getBrowser]; + return (browser != NULL); +} + +- (BOOL)acceptsFirstResponder { + CefRefPtr browser = [self getBrowser]; + return (browser != NULL); +} + +- (BOOL)becomeFirstResponder { + CefRefPtr browser = [self getBrowser]; + if (browser) { + browser->GetHost()->SendFocusEvent(true); + return [super becomeFirstResponder]; + } + + return NO; +} + +- (BOOL)resignFirstResponder { + CefRefPtr browser = [self getBrowser]; + if (browser) { + browser->GetHost()->SendFocusEvent(false); + return [super resignFirstResponder]; + } + + return NO; +} + +- (void)undo:(id)sender { + CefRefPtr browser = [self getBrowser]; + if (browser) + browser->GetFocusedFrame()->Undo(); +} + +- (void)redo:(id)sender { + CefRefPtr browser = [self getBrowser]; + if (browser) + browser->GetFocusedFrame()->Redo(); +} + +- (void)cut:(id)sender { + CefRefPtr browser = [self getBrowser]; + if (browser) + browser->GetFocusedFrame()->Cut(); +} + +- (void)copy:(id)sender { + CefRefPtr browser = [self getBrowser]; + if (browser) + browser->GetFocusedFrame()->Copy(); +} + +- (void)paste:(id)sender { + CefRefPtr browser = [self getBrowser]; + if (browser) + browser->GetFocusedFrame()->Paste(); +} + +- (void)delete:(id)sender { + CefRefPtr browser = [self getBrowser]; + if (browser) + browser->GetFocusedFrame()->Delete(); +} + +- (void)selectAll:(id)sender { + CefRefPtr browser = [self getBrowser]; + if (browser) + browser->GetFocusedFrame()->SelectAll(); +} + +- (NSPoint)getClickPointForEvent:(NSEvent*)event { + NSPoint windowLocal = [event locationInWindow]; + NSPoint contentLocal = [self convertPoint:windowLocal fromView:nil]; + + NSPoint point; + point.x = contentLocal.x; + point.y = [self frame].size.height - contentLocal.y; // Flip y. + return point; +} + +- (void)getKeyEvent:(CefKeyEvent &)keyEvent forEvent:(NSEvent *)event { + if ([event type] == NSKeyDown || [event type] == NSKeyUp) { + NSString* s = [event characters]; + if ([s length] > 0) + keyEvent.character = [s characterAtIndex:0]; + + s = [event charactersIgnoringModifiers]; + if ([s length] > 0) + keyEvent.unmodified_character = [s characterAtIndex:0]; + } + + if ([event type] == NSFlagsChanged) { + keyEvent.character = 0; + keyEvent.unmodified_character = 0; + } + + keyEvent.native_key_code = [event keyCode]; + + keyEvent.modifiers = [self getModifiersForEvent:event]; +} + +- (NSTextInputContext*)inputContext { + CefRefPtr browser = [self getBrowser]; + if (browser) + return browser->GetHost()->GetNSTextInputContext(); + return NULL; +} + +- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event { + NSPoint point = [self getClickPointForEvent:event]; + mouseEvent.x = point.x; + mouseEvent.y = point.y; + + if ([self isOverPopupWidgetX:mouseEvent.x andY: mouseEvent.y]) { + [self applyPopupOffsetToX:mouseEvent.x andY: mouseEvent.y]; + } + + mouseEvent.modifiers = [self getModifiersForEvent:event]; +} + +- (int)getModifiersForEvent:(NSEvent*)event { + int modifiers = 0; + + if ([event modifierFlags] & NSControlKeyMask) + modifiers |= EVENTFLAG_CONTROL_DOWN; + if ([event modifierFlags] & NSShiftKeyMask) + modifiers |= EVENTFLAG_SHIFT_DOWN; + if ([event modifierFlags] & NSAlternateKeyMask) + modifiers |= EVENTFLAG_ALT_DOWN; + if ([event modifierFlags] & NSCommandKeyMask) + modifiers |= EVENTFLAG_COMMAND_DOWN; + if ([event modifierFlags] & NSAlphaShiftKeyMask) + modifiers |= EVENTFLAG_CAPS_LOCK_ON; + + if ([event type] == NSKeyUp || + [event type] == NSKeyDown || + [event type] == NSFlagsChanged) { + // Only perform this check for key events + if ([self isKeyPadEvent:event]) + modifiers |= EVENTFLAG_IS_KEY_PAD; + } + + // OS X does not have a modifier for NumLock, so I'm not entirely sure how to + // set EVENTFLAG_NUM_LOCK_ON; + // + // There is no EVENTFLAG for the function key either. + + // Mouse buttons + switch ([event type]) { + case NSLeftMouseDragged: + case NSLeftMouseDown: + case NSLeftMouseUp: + modifiers |= EVENTFLAG_LEFT_MOUSE_BUTTON; + break; + case NSRightMouseDragged: + case NSRightMouseDown: + case NSRightMouseUp: + modifiers |= EVENTFLAG_RIGHT_MOUSE_BUTTON; + break; + case NSOtherMouseDragged: + case NSOtherMouseDown: + case NSOtherMouseUp: + modifiers |= EVENTFLAG_MIDDLE_MOUSE_BUTTON; + break; + } + + return modifiers; +} + +- (BOOL)isKeyUpEvent:(NSEvent*)event { + if ([event type] != NSFlagsChanged) + return [event type] == NSKeyUp; + + // FIXME: This logic fails if the user presses both Shift keys at once, for + // example: we treat releasing one of them as keyDown. + switch ([event keyCode]) { + case 54: // Right Command + case 55: // Left Command + return ([event modifierFlags] & NSCommandKeyMask) == 0; + + case 57: // Capslock + return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0; + + case 56: // Left Shift + case 60: // Right Shift + return ([event modifierFlags] & NSShiftKeyMask) == 0; + + case 58: // Left Alt + case 61: // Right Alt + return ([event modifierFlags] & NSAlternateKeyMask) == 0; + + case 59: // Left Ctrl + case 62: // Right Ctrl + return ([event modifierFlags] & NSControlKeyMask) == 0; + + case 63: // Function + return ([event modifierFlags] & NSFunctionKeyMask) == 0; + } + return false; +} + +- (BOOL)isKeyPadEvent:(NSEvent*)event { + if ([event modifierFlags] & NSNumericPadKeyMask) + return true; + + switch ([event keyCode]) { + case 71: // Clear + case 81: // = + case 75: // / + case 67: // * + case 78: // - + case 69: // + + case 76: // Enter + case 65: // . + case 82: // 0 + case 83: // 1 + case 84: // 2 + case 85: // 3 + case 86: // 4 + case 87: // 5 + case 88: // 6 + case 89: // 7 + case 91: // 8 + case 92: // 9 + return true; + } + + return false; +} + +- (void)windowDidChangeBackingProperties:(NSNotification*)notification { + // This delegate method is only called on 10.7 and later, so don't worry about + // other backing changes calling it on 10.6 or earlier + CGFloat newBackingScaleFactor = [self getDeviceScaleFactor]; + NSNumber* oldBackingScaleFactor = + [[notification userInfo] objectForKey:NSBackingPropertyOldScaleFactorKey]; + if (newBackingScaleFactor != [oldBackingScaleFactor doubleValue]) { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + browser->GetHost()->NotifyScreenInfoChanged(); + } +} + +- (void)drawRect: (NSRect) dirtyRect { + // The Invalidate below fixes flicker when resizing + if ([self inLiveResize]) { + CefRefPtr browser = [self getBrowser]; + if (!browser) + return; + + NSRect b = [self bounds]; + CefRect boundsRect = CefRect((int)b.origin.x, + (int)b.origin.y, + (int)b.size.width, + (int)b.size.height); + browser->GetHost()->Invalidate(boundsRect, PET_VIEW); + } +} + +// Utility - private +- (float)getDeviceScaleFactor { + float deviceScaleFactor = 1; + NSWindow* window = [self window]; + if (!window) + return deviceScaleFactor; + + if ([window respondsToSelector:@selector(backingScaleFactor)]) + deviceScaleFactor = [window backingScaleFactor]; + else + deviceScaleFactor = [window userSpaceScaleFactor]; + + return deviceScaleFactor; +} + +- (bool) isOverPopupWidgetX: (int) x andY: (int) y { + CefRect rc = [self convertRectFromBackingInternal:renderer_->popup_rect()]; + int popup_right = rc.x + rc.width; + int popup_bottom = rc.y + rc.height; + return (x >= rc.x) && (x < popup_right) && + (y >= rc.y) && (y < popup_bottom); +} + +- (int) getPopupXOffset { + int original_x = + [self convertRectFromBackingInternal:renderer_->original_popup_rect()].x; + int popup_x = + [self convertRectFromBackingInternal:renderer_->popup_rect()].x; + + return original_x - popup_x; +} + +- (int) getPopupYOffset { + int original_y = + [self convertRectFromBackingInternal:renderer_->original_popup_rect()].y; + int popup_y = + [self convertRectFromBackingInternal:renderer_->popup_rect()].y; + + return original_y - popup_y; +} + +- (void) applyPopupOffsetToX: (int&) x andY: (int&) y { + if ([self isOverPopupWidgetX:x andY:y]) { + x += [self getPopupXOffset]; + y += [self getPopupYOffset]; + } +} + +- (void) convertRects: (const CefRenderHandler::RectList&) rects + toBackingRects: (CefRenderHandler::RectList*) scaled_rects + andSize: (const NSSize) size + toBackingSize: (NSSize*) scaled_size { + *scaled_rects = rects; + *scaled_size = size; + + if ([self getDeviceScaleFactor] != 1 && + [self respondsToSelector:@selector(convertSizeToBacking:)] && + [self respondsToSelector:@selector(convertRectToBacking:)]) { + CefRenderHandler::RectList scaled_dirty_rects; + for (size_t i = 0; i < rects.size(); ++i) { + scaled_dirty_rects.push_back([self convertRectToBackingInternal:rects[i]]); + } + + *scaled_rects = scaled_dirty_rects; + *scaled_size = [self convertSizeToBacking:size]; + } +} + +- (CefRect) convertRectToBackingInternal: (const CefRect&) rect { + if ([self getDeviceScaleFactor] == 1) + return rect; + + if ([self respondsToSelector:@selector(convertRectToBacking:)]) { + NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); + NSRect scaled_rect = [self convertRectToBacking:old_rect]; + return CefRect((int)scaled_rect.origin.x, + (int)scaled_rect.origin.y, + (int)scaled_rect.size.width, + (int)scaled_rect.size.height); + } + + return rect; +} + +- (CefRect) convertRectFromBackingInternal: (const CefRect&) rect { + if ([self respondsToSelector:@selector(convertRectFromBacking:)]) { + NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); + NSRect scaled_rect = [self convertRectFromBacking:old_rect]; + return CefRect((int)scaled_rect.origin.x, + (int)scaled_rect.origin.y, + (int)scaled_rect.size.width, + (int)scaled_rect.size.height); + } + + return rect; +} + +@end + + +CefRefPtr OSRWindow::Create(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView, + const CefRect& frame) { + return new OSRWindow(browser_provider, transparent, parentView, frame); +} + +OSRWindow::OSRWindow(OSRBrowserProvider* browser_provider, + bool transparent, + CefWindowHandle parentView, + const CefRect& frame) { + NSRect window_rect = NSMakeRect(frame.x, frame.y, frame.width, frame.height); + ClientOpenGLView* view = [[ClientOpenGLView alloc] initWithFrame:window_rect + andTransparency:transparent]; + this->view_ = view; + [parentView addSubview:view]; + [view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [view setAutoresizesSubviews: true]; + + this->render_client = new ClientOSRHandler(view, browser_provider); +} + +OSRWindow::~OSRWindow() { +} diff --git a/tests/cefclient/res/osr_test.html b/tests/cefclient/res/osr_test.html index 3136bdef4..8e655a34c 100644 --- a/tests/cefclient/res/osr_test.html +++ b/tests/cefclient/res/osr_test.html @@ -1,69 +1,69 @@ - - OSR Test - - - -

- OSR Testing h1 - Focus and blur - - this page and will get this red black -

-
    -
  1. OnPaint should be called each time a page loads
  2. -
  3. Move mouse - to require an OnCursorChange call
  4. -
  5. Hover will color this with - red. Will trigger OnPaint once on enter and once on leave
  6. -
  7. Right clicking will show contextual menu and will request - GetScreenPoint
  8. -
  9. IsWindowRenderingDisabled should be true
  10. -
  11. WasResized should trigger full repaint if size changes. -
  12. -
  13. Invalidate should trigger OnPaint once
  14. -
  15. Click and write here with SendKeyEvent to trigger repaints: -
  16. -
  17. Click here with SendMouseClickEvent to navigate: -
  18. -
  19. Mouse over this element will - trigger show a tooltip
  20. -
-
-
-
-
-
-
- - + + OSR Test + + + +

+ OSR Testing h1 - Focus and blur + + this page and will get this red black +

+
    +
  1. OnPaint should be called each time a page loads
  2. +
  3. Move mouse + to require an OnCursorChange call
  4. +
  5. Hover will color this with + red. Will trigger OnPaint once on enter and once on leave
  6. +
  7. Right clicking will show contextual menu and will request + GetScreenPoint
  8. +
  9. IsWindowRenderingDisabled should be true
  10. +
  11. WasResized should trigger full repaint if size changes. +
  12. +
  13. Invalidate should trigger OnPaint once
  14. +
  15. Click and write here with SendKeyEvent to trigger repaints: +
  16. +
  17. Click here with SendMouseClickEvent to navigate: +
  18. +
  19. Mouse over this element will + trigger show a tooltip
  20. +
+
+
+
+
+
+
+ + diff --git a/tests/cefclient/res/other_tests.html b/tests/cefclient/res/other_tests.html index 81b523e9f..4da1afb5e 100644 --- a/tests/cefclient/res/other_tests.html +++ b/tests/cefclient/res/other_tests.html @@ -1,32 +1,32 @@ - - -Other Tests - - -

Various other internal and external tests.

- - - + + +Other Tests + + +

Various other internal and external tests.

+ + + diff --git a/tests/cefclient/res/performance2.html b/tests/cefclient/res/performance2.html index bd3dcf99d..6664de7b2 100644 --- a/tests/cefclient/res/performance2.html +++ b/tests/cefclient/res/performance2.html @@ -1,442 +1,442 @@ - - - - Performance Tests (2) - - - -

Performance Tests (2)

- -
- - - - - - - - - - - - - - - - - - - -
Settings:
Iterations:
Samples:
Mode:Asynchronous - Synchronous -
-
- - -
- -
- - - - - - - - - - - - - - - - - - - -
EnabledNameSamples x IterationsMin, msAvg, msMax, msAverage calls/secMeasuring InacurracyMemory, MBMemory delta, MBDescription
-
- - - - - + + + + Performance Tests (2) + + + +

Performance Tests (2)

+ +
+ + + + + + + + + + + + + + + + + + + +
Settings:
Iterations:
Samples:
Mode:Asynchronous + Synchronous +
+
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + +
EnabledNameSamples x IterationsMin, msAvg, msMax, msAverage calls/secMeasuring InacurracyMemory, MBMemory delta, MBDescription
+
+ + + + + diff --git a/tests/cefclient/window_test_win.cpp b/tests/cefclient/window_test_win.cpp index 2a6e44fad..f905e4312 100644 --- a/tests/cefclient/window_test_win.cpp +++ b/tests/cefclient/window_test_win.cpp @@ -1,78 +1,78 @@ -// Copyright (c) 2013 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 "cefclient/window_test.h" - -namespace window_test { - -namespace { - -// Toggles the current display state. -void Toggle(CefWindowHandle handle, UINT nCmdShow) { - HWND root_wnd = ::GetAncestor(handle, GA_ROOT); - - // Retrieve current window placement information. - WINDOWPLACEMENT placement; - ::GetWindowPlacement(root_wnd, &placement); - - if (placement.showCmd == nCmdShow) - ::ShowWindow(root_wnd, SW_RESTORE); - else - ::ShowWindow(root_wnd, nCmdShow); -} - -} // namespace - -void SetPos(CefWindowHandle handle, int x, int y, int width, int height) { - HWND root_wnd = ::GetAncestor(handle, GA_ROOT); - - // Retrieve current window placement information. - WINDOWPLACEMENT placement; - ::GetWindowPlacement(root_wnd, &placement); - - // Retrieve information about the display that contains the window. - HMONITOR monitor = MonitorFromRect(&placement.rcNormalPosition, - MONITOR_DEFAULTTONEAREST); - MONITORINFO info; - info.cbSize = sizeof(info); - GetMonitorInfo(monitor, &info); - - // Make sure the window is inside the display. - CefRect display_rect( - info.rcWork.left, - info.rcWork.top, - info.rcWork.right - info.rcWork.left, - info.rcWork.bottom - info.rcWork.top); - CefRect window_rect(x, y, width, height); - ModifyBounds(display_rect, window_rect); - - if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_MAXIMIZE) { - // The window is currently minimized or maximized. Restore it to the desired - // position. - placement.rcNormalPosition.left = window_rect.x; - placement.rcNormalPosition.right = window_rect.x + window_rect.width; - placement.rcNormalPosition.top = window_rect.y; - placement.rcNormalPosition.bottom = window_rect.y + window_rect.height; - ::SetWindowPlacement(root_wnd, &placement); - ::ShowWindow(root_wnd, SW_RESTORE); - } else { - // Set the window position. - ::SetWindowPos(root_wnd, NULL, window_rect.x, window_rect.y, - window_rect.width, window_rect.height, SWP_NOZORDER); - } -} - -void Minimize(CefWindowHandle handle) { - Toggle(handle, SW_MINIMIZE); -} - -void Maximize(CefWindowHandle handle) { - Toggle(handle, SW_MAXIMIZE); -} - -void Restore(CefWindowHandle handle) { - ::ShowWindow(::GetAncestor(handle, GA_ROOT), SW_RESTORE); -} - -} // namespace window_test +// Copyright (c) 2013 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 "cefclient/window_test.h" + +namespace window_test { + +namespace { + +// Toggles the current display state. +void Toggle(CefWindowHandle handle, UINT nCmdShow) { + HWND root_wnd = ::GetAncestor(handle, GA_ROOT); + + // Retrieve current window placement information. + WINDOWPLACEMENT placement; + ::GetWindowPlacement(root_wnd, &placement); + + if (placement.showCmd == nCmdShow) + ::ShowWindow(root_wnd, SW_RESTORE); + else + ::ShowWindow(root_wnd, nCmdShow); +} + +} // namespace + +void SetPos(CefWindowHandle handle, int x, int y, int width, int height) { + HWND root_wnd = ::GetAncestor(handle, GA_ROOT); + + // Retrieve current window placement information. + WINDOWPLACEMENT placement; + ::GetWindowPlacement(root_wnd, &placement); + + // Retrieve information about the display that contains the window. + HMONITOR monitor = MonitorFromRect(&placement.rcNormalPosition, + MONITOR_DEFAULTTONEAREST); + MONITORINFO info; + info.cbSize = sizeof(info); + GetMonitorInfo(monitor, &info); + + // Make sure the window is inside the display. + CefRect display_rect( + info.rcWork.left, + info.rcWork.top, + info.rcWork.right - info.rcWork.left, + info.rcWork.bottom - info.rcWork.top); + CefRect window_rect(x, y, width, height); + ModifyBounds(display_rect, window_rect); + + if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_MAXIMIZE) { + // The window is currently minimized or maximized. Restore it to the desired + // position. + placement.rcNormalPosition.left = window_rect.x; + placement.rcNormalPosition.right = window_rect.x + window_rect.width; + placement.rcNormalPosition.top = window_rect.y; + placement.rcNormalPosition.bottom = window_rect.y + window_rect.height; + ::SetWindowPlacement(root_wnd, &placement); + ::ShowWindow(root_wnd, SW_RESTORE); + } else { + // Set the window position. + ::SetWindowPos(root_wnd, NULL, window_rect.x, window_rect.y, + window_rect.width, window_rect.height, SWP_NOZORDER); + } +} + +void Minimize(CefWindowHandle handle) { + Toggle(handle, SW_MINIMIZE); +} + +void Maximize(CefWindowHandle handle) { + Toggle(handle, SW_MAXIMIZE); +} + +void Restore(CefWindowHandle handle) { + ::ShowWindow(::GetAncestor(handle, GA_ROOT), SW_RESTORE); +} + +} // namespace window_test diff --git a/tests/unittests/download_unittest.cc b/tests/unittests/download_unittest.cc index 14c09aaf9..9c67eea55 100644 --- a/tests/unittests/download_unittest.cc +++ b/tests/unittests/download_unittest.cc @@ -1,262 +1,262 @@ -// Copyright (c) 2013 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 "include/cef_scheme.h" -#include "base/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "tests/unittests/test_handler.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -const char kTestDomain[] = "test-download"; -const char kTestEntryUrl[] = "http://test-download/test.html"; -const char kTestDownloadUrl[] = "http://test-download/download.txt"; -const char kTestFileName[] = "download_test.txt"; -const char kTestContentDisposition[] = - "attachment; filename=\"download_test.txt\""; -const char kTestMimeType[] = "text/plain"; -const char kTestContent[] = "Download test text"; - -class DownloadSchemeHandler : public CefResourceHandler { - public: - explicit DownloadSchemeHandler(TrackCallback* got_download_request) - : got_download_request_(got_download_request), - offset_(0) {} - - virtual bool ProcessRequest(CefRefPtr request, - CefRefPtr callback) - OVERRIDE { - std::string url = request->GetURL(); - if (url == kTestEntryUrl) { - content_ = "Download Test"; - mime_type_ = "text/html"; - } else if (url == kTestDownloadUrl) { - got_download_request_->yes(); - content_ = kTestContent; - mime_type_ = kTestMimeType; - content_disposition_ = kTestContentDisposition; - } else { - EXPECT_TRUE(false); // Not reached. - return false; - } - - callback->Continue(); - return true; - } - - virtual void GetResponseHeaders(CefRefPtr response, - int64& response_length, - CefString& redirectUrl) OVERRIDE { - response_length = content_.size(); - - response->SetStatus(200); - response->SetMimeType(mime_type_); - - if (!content_disposition_.empty()) { - CefResponse::HeaderMap headerMap; - response->GetHeaderMap(headerMap); - headerMap.insert( - std::make_pair("Content-Disposition", content_disposition_)); - response->SetHeaderMap(headerMap); - } - } - - virtual bool ReadResponse(void* data_out, - int bytes_to_read, - int& bytes_read, - CefRefPtr callback) - OVERRIDE { - bool has_data = false; - bytes_read = 0; - - size_t size = content_.size(); - if (offset_ < size) { - int transfer_size = - std::min(bytes_to_read, static_cast(size - offset_)); - memcpy(data_out, content_.c_str() + offset_, transfer_size); - offset_ += transfer_size; - - bytes_read = transfer_size; - has_data = true; - } - - return has_data; - } - - virtual void Cancel() OVERRIDE { - } - - private: - TrackCallback* got_download_request_; - std::string content_; - std::string mime_type_; - std::string content_disposition_; - size_t offset_; - - IMPLEMENT_REFCOUNTING(SchemeHandler); -}; - -class DownloadSchemeHandlerFactory : public CefSchemeHandlerFactory { - public: - explicit DownloadSchemeHandlerFactory(TrackCallback* got_download_request) - : got_download_request_(got_download_request) {} - - virtual CefRefPtr Create( - CefRefPtr browser, - CefRefPtr frame, - const CefString& scheme_name, - CefRefPtr request) OVERRIDE { - return new DownloadSchemeHandler(got_download_request_); - } - - private: - TrackCallback* got_download_request_; - - IMPLEMENT_REFCOUNTING(SchemeHandlerFactory); -}; - -class DownloadTestHandler : public TestHandler { - public: - DownloadTestHandler() {} - - virtual void RunTest() OVERRIDE { - CefRegisterSchemeHandlerFactory("http", kTestDomain, - new DownloadSchemeHandlerFactory(&got_download_request_)); - - // Create a new temporary directory. - EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); - test_path_ = temp_dir_.path().AppendASCII(kTestFileName); - - // Create the browser - CreateBrowser(kTestEntryUrl); - } - - virtual void OnLoadEnd(CefRefPtr browser, - CefRefPtr frame, - int httpStatusCode) OVERRIDE { - EXPECT_STREQ(kTestEntryUrl, frame->GetURL().ToString().c_str()); - - // Begin the download. - browser->GetHost()->StartDownload(kTestDownloadUrl); - } - - virtual void OnBeforeDownload( - CefRefPtr browser, - CefRefPtr download_item, - const CefString& suggested_name, - CefRefPtr callback) OVERRIDE { - EXPECT_TRUE(CefCurrentlyOn(TID_UI)); - EXPECT_FALSE(got_on_before_download_); - - got_on_before_download_.yes(); - - EXPECT_TRUE(browser->IsSame(GetBrowser())); - EXPECT_STREQ(kTestFileName, suggested_name.ToString().c_str()); - EXPECT_TRUE(download_item.get()); - EXPECT_TRUE(callback.get()); - - download_id_ = download_item->GetId(); - EXPECT_LT(0U, download_id_); - - EXPECT_TRUE(download_item->IsValid()); - EXPECT_TRUE(download_item->IsInProgress()); - EXPECT_FALSE(download_item->IsComplete()); - EXPECT_FALSE(download_item->IsCanceled()); - EXPECT_EQ(static_cast(sizeof(kTestContent)-1), - download_item->GetTotalBytes()); - EXPECT_EQ(0UL, download_item->GetFullPath().length()); - EXPECT_STREQ(kTestDownloadUrl, download_item->GetURL().ToString().c_str()); - EXPECT_EQ(0UL, download_item->GetSuggestedFileName().length()); - EXPECT_STREQ(kTestContentDisposition, - download_item->GetContentDisposition().ToString().c_str()); - EXPECT_STREQ(kTestMimeType, download_item->GetMimeType().ToString().c_str()); - - callback->Continue(test_path_.value(), false); - } - - virtual void OnDownloadUpdated( - CefRefPtr browser, - CefRefPtr download_item, - CefRefPtr callback) OVERRIDE { - EXPECT_TRUE(CefCurrentlyOn(TID_UI)); - - got_on_download_updated_.yes(); - - EXPECT_TRUE(browser->IsSame(GetBrowser())); - EXPECT_TRUE(download_item.get()); - EXPECT_TRUE(callback.get()); - - if (got_on_before_download_) - EXPECT_EQ(download_id_, download_item->GetId()); - - EXPECT_LE(0LL, download_item->GetCurrentSpeed()); - EXPECT_LE(0, download_item->GetPercentComplete()); - - EXPECT_TRUE(download_item->IsValid()); - EXPECT_FALSE(download_item->IsCanceled()); - EXPECT_STREQ(kTestDownloadUrl, download_item->GetURL().ToString().c_str()); - EXPECT_STREQ(kTestContentDisposition, - download_item->GetContentDisposition().ToString().c_str()); - EXPECT_STREQ(kTestMimeType, - download_item->GetMimeType().ToString().c_str()); - - std::string full_path = download_item->GetFullPath(); - if (!full_path.empty()) { - got_full_path_.yes(); - EXPECT_STREQ(CefString(test_path_.value()).ToString().c_str(), - full_path.c_str()); - } - - if (download_item->IsComplete()) { - EXPECT_FALSE(download_item->IsInProgress()); - EXPECT_EQ(100, download_item->GetPercentComplete()); - EXPECT_EQ(static_cast(sizeof(kTestContent)-1), - download_item->GetReceivedBytes()); - EXPECT_EQ(static_cast(sizeof(kTestContent)-1), - download_item->GetTotalBytes()); - - DestroyTest(); - } else { - EXPECT_TRUE(download_item->IsInProgress()); - EXPECT_LE(0LL, download_item->GetReceivedBytes()); - } - } - - virtual void DestroyTest() OVERRIDE { - CefRegisterSchemeHandlerFactory("http", kTestDomain, NULL); - - EXPECT_TRUE(got_download_request_); - EXPECT_TRUE(got_on_before_download_); - EXPECT_TRUE(got_on_download_updated_); - EXPECT_TRUE(got_full_path_); - - // Verify the file contents. - std::string contents; - EXPECT_TRUE(base::ReadFileToString(test_path_, &contents)); - EXPECT_STREQ(kTestContent, contents.c_str()); - - EXPECT_TRUE(temp_dir_.Delete()); - - TestHandler::DestroyTest(); - } - - private: - base::ScopedTempDir temp_dir_; - base::FilePath test_path_; - uint32 download_id_; - - TrackCallback got_download_request_; - TrackCallback got_on_before_download_; - TrackCallback got_on_download_updated_; - TrackCallback got_full_path_; -}; - -} // namespace - -// Verify that downloads work. -TEST(DownloadTest, Download) { - CefRefPtr handler = new DownloadTestHandler(); - handler->ExecuteTest(); -} +// Copyright (c) 2013 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 "include/cef_scheme.h" +#include "base/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "tests/unittests/test_handler.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kTestDomain[] = "test-download"; +const char kTestEntryUrl[] = "http://test-download/test.html"; +const char kTestDownloadUrl[] = "http://test-download/download.txt"; +const char kTestFileName[] = "download_test.txt"; +const char kTestContentDisposition[] = + "attachment; filename=\"download_test.txt\""; +const char kTestMimeType[] = "text/plain"; +const char kTestContent[] = "Download test text"; + +class DownloadSchemeHandler : public CefResourceHandler { + public: + explicit DownloadSchemeHandler(TrackCallback* got_download_request) + : got_download_request_(got_download_request), + offset_(0) {} + + virtual bool ProcessRequest(CefRefPtr request, + CefRefPtr callback) + OVERRIDE { + std::string url = request->GetURL(); + if (url == kTestEntryUrl) { + content_ = "Download Test"; + mime_type_ = "text/html"; + } else if (url == kTestDownloadUrl) { + got_download_request_->yes(); + content_ = kTestContent; + mime_type_ = kTestMimeType; + content_disposition_ = kTestContentDisposition; + } else { + EXPECT_TRUE(false); // Not reached. + return false; + } + + callback->Continue(); + return true; + } + + virtual void GetResponseHeaders(CefRefPtr response, + int64& response_length, + CefString& redirectUrl) OVERRIDE { + response_length = content_.size(); + + response->SetStatus(200); + response->SetMimeType(mime_type_); + + if (!content_disposition_.empty()) { + CefResponse::HeaderMap headerMap; + response->GetHeaderMap(headerMap); + headerMap.insert( + std::make_pair("Content-Disposition", content_disposition_)); + response->SetHeaderMap(headerMap); + } + } + + virtual bool ReadResponse(void* data_out, + int bytes_to_read, + int& bytes_read, + CefRefPtr callback) + OVERRIDE { + bool has_data = false; + bytes_read = 0; + + size_t size = content_.size(); + if (offset_ < size) { + int transfer_size = + std::min(bytes_to_read, static_cast(size - offset_)); + memcpy(data_out, content_.c_str() + offset_, transfer_size); + offset_ += transfer_size; + + bytes_read = transfer_size; + has_data = true; + } + + return has_data; + } + + virtual void Cancel() OVERRIDE { + } + + private: + TrackCallback* got_download_request_; + std::string content_; + std::string mime_type_; + std::string content_disposition_; + size_t offset_; + + IMPLEMENT_REFCOUNTING(SchemeHandler); +}; + +class DownloadSchemeHandlerFactory : public CefSchemeHandlerFactory { + public: + explicit DownloadSchemeHandlerFactory(TrackCallback* got_download_request) + : got_download_request_(got_download_request) {} + + virtual CefRefPtr Create( + CefRefPtr browser, + CefRefPtr frame, + const CefString& scheme_name, + CefRefPtr request) OVERRIDE { + return new DownloadSchemeHandler(got_download_request_); + } + + private: + TrackCallback* got_download_request_; + + IMPLEMENT_REFCOUNTING(SchemeHandlerFactory); +}; + +class DownloadTestHandler : public TestHandler { + public: + DownloadTestHandler() {} + + virtual void RunTest() OVERRIDE { + CefRegisterSchemeHandlerFactory("http", kTestDomain, + new DownloadSchemeHandlerFactory(&got_download_request_)); + + // Create a new temporary directory. + EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); + test_path_ = temp_dir_.path().AppendASCII(kTestFileName); + + // Create the browser + CreateBrowser(kTestEntryUrl); + } + + virtual void OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) OVERRIDE { + EXPECT_STREQ(kTestEntryUrl, frame->GetURL().ToString().c_str()); + + // Begin the download. + browser->GetHost()->StartDownload(kTestDownloadUrl); + } + + virtual void OnBeforeDownload( + CefRefPtr browser, + CefRefPtr download_item, + const CefString& suggested_name, + CefRefPtr callback) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_UI)); + EXPECT_FALSE(got_on_before_download_); + + got_on_before_download_.yes(); + + EXPECT_TRUE(browser->IsSame(GetBrowser())); + EXPECT_STREQ(kTestFileName, suggested_name.ToString().c_str()); + EXPECT_TRUE(download_item.get()); + EXPECT_TRUE(callback.get()); + + download_id_ = download_item->GetId(); + EXPECT_LT(0U, download_id_); + + EXPECT_TRUE(download_item->IsValid()); + EXPECT_TRUE(download_item->IsInProgress()); + EXPECT_FALSE(download_item->IsComplete()); + EXPECT_FALSE(download_item->IsCanceled()); + EXPECT_EQ(static_cast(sizeof(kTestContent)-1), + download_item->GetTotalBytes()); + EXPECT_EQ(0UL, download_item->GetFullPath().length()); + EXPECT_STREQ(kTestDownloadUrl, download_item->GetURL().ToString().c_str()); + EXPECT_EQ(0UL, download_item->GetSuggestedFileName().length()); + EXPECT_STREQ(kTestContentDisposition, + download_item->GetContentDisposition().ToString().c_str()); + EXPECT_STREQ(kTestMimeType, download_item->GetMimeType().ToString().c_str()); + + callback->Continue(test_path_.value(), false); + } + + virtual void OnDownloadUpdated( + CefRefPtr browser, + CefRefPtr download_item, + CefRefPtr callback) OVERRIDE { + EXPECT_TRUE(CefCurrentlyOn(TID_UI)); + + got_on_download_updated_.yes(); + + EXPECT_TRUE(browser->IsSame(GetBrowser())); + EXPECT_TRUE(download_item.get()); + EXPECT_TRUE(callback.get()); + + if (got_on_before_download_) + EXPECT_EQ(download_id_, download_item->GetId()); + + EXPECT_LE(0LL, download_item->GetCurrentSpeed()); + EXPECT_LE(0, download_item->GetPercentComplete()); + + EXPECT_TRUE(download_item->IsValid()); + EXPECT_FALSE(download_item->IsCanceled()); + EXPECT_STREQ(kTestDownloadUrl, download_item->GetURL().ToString().c_str()); + EXPECT_STREQ(kTestContentDisposition, + download_item->GetContentDisposition().ToString().c_str()); + EXPECT_STREQ(kTestMimeType, + download_item->GetMimeType().ToString().c_str()); + + std::string full_path = download_item->GetFullPath(); + if (!full_path.empty()) { + got_full_path_.yes(); + EXPECT_STREQ(CefString(test_path_.value()).ToString().c_str(), + full_path.c_str()); + } + + if (download_item->IsComplete()) { + EXPECT_FALSE(download_item->IsInProgress()); + EXPECT_EQ(100, download_item->GetPercentComplete()); + EXPECT_EQ(static_cast(sizeof(kTestContent)-1), + download_item->GetReceivedBytes()); + EXPECT_EQ(static_cast(sizeof(kTestContent)-1), + download_item->GetTotalBytes()); + + DestroyTest(); + } else { + EXPECT_TRUE(download_item->IsInProgress()); + EXPECT_LE(0LL, download_item->GetReceivedBytes()); + } + } + + virtual void DestroyTest() OVERRIDE { + CefRegisterSchemeHandlerFactory("http", kTestDomain, NULL); + + EXPECT_TRUE(got_download_request_); + EXPECT_TRUE(got_on_before_download_); + EXPECT_TRUE(got_on_download_updated_); + EXPECT_TRUE(got_full_path_); + + // Verify the file contents. + std::string contents; + EXPECT_TRUE(base::ReadFileToString(test_path_, &contents)); + EXPECT_STREQ(kTestContent, contents.c_str()); + + EXPECT_TRUE(temp_dir_.Delete()); + + TestHandler::DestroyTest(); + } + + private: + base::ScopedTempDir temp_dir_; + base::FilePath test_path_; + uint32 download_id_; + + TrackCallback got_download_request_; + TrackCallback got_on_before_download_; + TrackCallback got_on_download_updated_; + TrackCallback got_full_path_; +}; + +} // namespace + +// Verify that downloads work. +TEST(DownloadTest, Download) { + CefRefPtr handler = new DownloadTestHandler(); + handler->ExecuteTest(); +} diff --git a/tests/unittests/life_span_unittest.cc b/tests/unittests/life_span_unittest.cc index 2ac45d179..3b14b3528 100644 --- a/tests/unittests/life_span_unittest.cc +++ b/tests/unittests/life_span_unittest.cc @@ -1,306 +1,306 @@ -// Copyright (c) 2013 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 "include/cef_runnable.h" -#include "tests/unittests/test_handler.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -const char kLifeSpanUrl[] = "http://tests-life-span/test.html"; -const char kUnloadDialogText[] = "Are you sure?"; -const char kUnloadMsg[] = "LifeSpanTestHandler.Unload"; - -// Browser side. -class LifeSpanTestHandler : public TestHandler { - public: - struct Settings { - Settings() - : force_close(false), - add_onunload_handler(false), - allow_do_close(true), - accept_before_unload_dialog(true) {} - - bool force_close; - bool add_onunload_handler; - bool allow_do_close; - bool accept_before_unload_dialog; - }; - - explicit LifeSpanTestHandler(const Settings& settings) - : settings_(settings), - executing_delay_close_(false) {} - - virtual void RunTest() OVERRIDE { - // Add the resources that we will navigate to/from. - std::string page = "Page"; - AddResource(kLifeSpanUrl, page, "text/html"); - - // Create the browser. - CreateBrowser(kLifeSpanUrl); - } - - virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE { - got_after_created_.yes(); - TestHandler::OnAfterCreated(browser); - } - - virtual bool DoClose(CefRefPtr browser) OVERRIDE { - if (executing_delay_close_) - return false; - - EXPECT_TRUE(browser->IsSame(GetBrowser())); - - got_do_close_.yes(); - - if (!settings_.allow_do_close) { - // The close will be canceled. - ScheduleDelayClose(); - } - - return !settings_.allow_do_close; - } - - virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE { - if (!executing_delay_close_) { - got_before_close_.yes(); - EXPECT_TRUE(browser->IsSame(GetBrowser())); - } - - TestHandler::OnBeforeClose(browser); - } - - virtual bool OnBeforeUnloadDialog( - CefRefPtr browser, - const CefString& message_text, - bool is_reload, - CefRefPtr callback) OVERRIDE { - if (executing_delay_close_) { - callback->Continue(true, CefString()); - return true; - } - - EXPECT_TRUE(browser->IsSame(GetBrowser())); - EXPECT_STREQ(kUnloadDialogText, message_text.ToString().c_str()); - EXPECT_FALSE(is_reload); - EXPECT_TRUE(callback.get()); - - if (!settings_.accept_before_unload_dialog) { - // The close will be canceled. - ScheduleDelayClose(); - } - - got_before_unload_dialog_.yes(); - callback->Continue(settings_.accept_before_unload_dialog, CefString()); - return true; - } - - virtual void OnLoadEnd(CefRefPtr browser, - CefRefPtr frame, - int httpStatusCode) OVERRIDE { - got_load_end_.yes(); - EXPECT_TRUE(browser->IsSame(GetBrowser())); - - // Attempt to close the browser. - browser->GetHost()->CloseBrowser(settings_.force_close); - } - - virtual bool OnProcessMessageReceived( - CefRefPtr browser, - CefProcessId source_process, - CefRefPtr message) OVERRIDE { - const std::string& message_name = message->GetName(); - if (message_name == kUnloadMsg) { - if (!executing_delay_close_) - got_unload_message_.yes(); - return true; - } - - return false; - } - - TrackCallback got_after_created_; - TrackCallback got_do_close_; - TrackCallback got_before_close_; - TrackCallback got_before_unload_dialog_; - TrackCallback got_unload_message_; - TrackCallback got_load_end_; - TrackCallback got_delay_close_; - - private: - // Wait a bit to make sure no additional events are received and then close - // the window. - void ScheduleDelayClose() { - CefPostDelayedTask(TID_UI, - NewCefRunnableMethod(this, &LifeSpanTestHandler::DelayClose), 100); - } - - void DelayClose() { - got_delay_close_.yes(); - executing_delay_close_ = true; - DestroyTest(); - } - - Settings settings_; - - // Forces the window to close (bypasses test conditions). - bool executing_delay_close_; -}; - -} // namespace - -TEST(LifeSpanTest, DoCloseAllow) { - LifeSpanTestHandler::Settings settings; - settings.allow_do_close = true; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_TRUE(handler->got_before_close_); - EXPECT_FALSE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_FALSE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, DoCloseAllowForce) { - LifeSpanTestHandler::Settings settings; - settings.allow_do_close = true; - settings.force_close = true; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_TRUE(handler->got_before_close_); - EXPECT_FALSE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_FALSE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, DoCloseDisallow) { - LifeSpanTestHandler::Settings settings; - settings.allow_do_close = false; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_FALSE(handler->got_before_close_); - EXPECT_FALSE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_TRUE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, DoCloseDisallowForce) { - LifeSpanTestHandler::Settings settings; - settings.allow_do_close = false; - settings.force_close = true; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_FALSE(handler->got_before_close_); - EXPECT_FALSE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_TRUE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadAllow) { - LifeSpanTestHandler::Settings settings; - settings.allow_do_close = false; - settings.add_onunload_handler = true; - settings.accept_before_unload_dialog = true; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_FALSE(handler->got_before_close_); - EXPECT_TRUE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_TRUE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, DoCloseAllowWithOnUnloadForce) { - LifeSpanTestHandler::Settings settings; - settings.allow_do_close = true; - settings.add_onunload_handler = true; - settings.force_close = true; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_TRUE(handler->got_before_close_); - EXPECT_FALSE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_FALSE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadForce) { - LifeSpanTestHandler::Settings settings; - settings.allow_do_close = false; - settings.add_onunload_handler = true; - settings.force_close = true; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_FALSE(handler->got_before_close_); - EXPECT_FALSE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_TRUE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, OnUnloadAllow) { - LifeSpanTestHandler::Settings settings; - settings.add_onunload_handler = true; - settings.accept_before_unload_dialog = true; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_TRUE(handler->got_do_close_); - EXPECT_TRUE(handler->got_before_close_); - EXPECT_TRUE(handler->got_before_unload_dialog_); - EXPECT_TRUE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_FALSE(handler->got_delay_close_); -} - -TEST(LifeSpanTest, OnUnloadDisallow) { - LifeSpanTestHandler::Settings settings; - settings.add_onunload_handler = true; - settings.accept_before_unload_dialog = false; - CefRefPtr handler = new LifeSpanTestHandler(settings); - handler->ExecuteTest(); - - EXPECT_TRUE(handler->got_after_created_); - EXPECT_FALSE(handler->got_do_close_); - EXPECT_FALSE(handler->got_before_close_); - EXPECT_TRUE(handler->got_before_unload_dialog_); - EXPECT_FALSE(handler->got_unload_message_); - EXPECT_TRUE(handler->got_load_end_); - EXPECT_TRUE(handler->got_delay_close_); -} +// Copyright (c) 2013 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 "include/cef_runnable.h" +#include "tests/unittests/test_handler.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kLifeSpanUrl[] = "http://tests-life-span/test.html"; +const char kUnloadDialogText[] = "Are you sure?"; +const char kUnloadMsg[] = "LifeSpanTestHandler.Unload"; + +// Browser side. +class LifeSpanTestHandler : public TestHandler { + public: + struct Settings { + Settings() + : force_close(false), + add_onunload_handler(false), + allow_do_close(true), + accept_before_unload_dialog(true) {} + + bool force_close; + bool add_onunload_handler; + bool allow_do_close; + bool accept_before_unload_dialog; + }; + + explicit LifeSpanTestHandler(const Settings& settings) + : settings_(settings), + executing_delay_close_(false) {} + + virtual void RunTest() OVERRIDE { + // Add the resources that we will navigate to/from. + std::string page = "Page"; + AddResource(kLifeSpanUrl, page, "text/html"); + + // Create the browser. + CreateBrowser(kLifeSpanUrl); + } + + virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE { + got_after_created_.yes(); + TestHandler::OnAfterCreated(browser); + } + + virtual bool DoClose(CefRefPtr browser) OVERRIDE { + if (executing_delay_close_) + return false; + + EXPECT_TRUE(browser->IsSame(GetBrowser())); + + got_do_close_.yes(); + + if (!settings_.allow_do_close) { + // The close will be canceled. + ScheduleDelayClose(); + } + + return !settings_.allow_do_close; + } + + virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE { + if (!executing_delay_close_) { + got_before_close_.yes(); + EXPECT_TRUE(browser->IsSame(GetBrowser())); + } + + TestHandler::OnBeforeClose(browser); + } + + virtual bool OnBeforeUnloadDialog( + CefRefPtr browser, + const CefString& message_text, + bool is_reload, + CefRefPtr callback) OVERRIDE { + if (executing_delay_close_) { + callback->Continue(true, CefString()); + return true; + } + + EXPECT_TRUE(browser->IsSame(GetBrowser())); + EXPECT_STREQ(kUnloadDialogText, message_text.ToString().c_str()); + EXPECT_FALSE(is_reload); + EXPECT_TRUE(callback.get()); + + if (!settings_.accept_before_unload_dialog) { + // The close will be canceled. + ScheduleDelayClose(); + } + + got_before_unload_dialog_.yes(); + callback->Continue(settings_.accept_before_unload_dialog, CefString()); + return true; + } + + virtual void OnLoadEnd(CefRefPtr browser, + CefRefPtr frame, + int httpStatusCode) OVERRIDE { + got_load_end_.yes(); + EXPECT_TRUE(browser->IsSame(GetBrowser())); + + // Attempt to close the browser. + browser->GetHost()->CloseBrowser(settings_.force_close); + } + + virtual bool OnProcessMessageReceived( + CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) OVERRIDE { + const std::string& message_name = message->GetName(); + if (message_name == kUnloadMsg) { + if (!executing_delay_close_) + got_unload_message_.yes(); + return true; + } + + return false; + } + + TrackCallback got_after_created_; + TrackCallback got_do_close_; + TrackCallback got_before_close_; + TrackCallback got_before_unload_dialog_; + TrackCallback got_unload_message_; + TrackCallback got_load_end_; + TrackCallback got_delay_close_; + + private: + // Wait a bit to make sure no additional events are received and then close + // the window. + void ScheduleDelayClose() { + CefPostDelayedTask(TID_UI, + NewCefRunnableMethod(this, &LifeSpanTestHandler::DelayClose), 100); + } + + void DelayClose() { + got_delay_close_.yes(); + executing_delay_close_ = true; + DestroyTest(); + } + + Settings settings_; + + // Forces the window to close (bypasses test conditions). + bool executing_delay_close_; +}; + +} // namespace + +TEST(LifeSpanTest, DoCloseAllow) { + LifeSpanTestHandler::Settings settings; + settings.allow_do_close = true; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_TRUE(handler->got_before_close_); + EXPECT_FALSE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_FALSE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, DoCloseAllowForce) { + LifeSpanTestHandler::Settings settings; + settings.allow_do_close = true; + settings.force_close = true; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_TRUE(handler->got_before_close_); + EXPECT_FALSE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_FALSE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, DoCloseDisallow) { + LifeSpanTestHandler::Settings settings; + settings.allow_do_close = false; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_FALSE(handler->got_before_close_); + EXPECT_FALSE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_TRUE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, DoCloseDisallowForce) { + LifeSpanTestHandler::Settings settings; + settings.allow_do_close = false; + settings.force_close = true; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_FALSE(handler->got_before_close_); + EXPECT_FALSE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_TRUE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadAllow) { + LifeSpanTestHandler::Settings settings; + settings.allow_do_close = false; + settings.add_onunload_handler = true; + settings.accept_before_unload_dialog = true; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_FALSE(handler->got_before_close_); + EXPECT_TRUE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_TRUE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, DoCloseAllowWithOnUnloadForce) { + LifeSpanTestHandler::Settings settings; + settings.allow_do_close = true; + settings.add_onunload_handler = true; + settings.force_close = true; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_TRUE(handler->got_before_close_); + EXPECT_FALSE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_FALSE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadForce) { + LifeSpanTestHandler::Settings settings; + settings.allow_do_close = false; + settings.add_onunload_handler = true; + settings.force_close = true; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_FALSE(handler->got_before_close_); + EXPECT_FALSE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_TRUE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, OnUnloadAllow) { + LifeSpanTestHandler::Settings settings; + settings.add_onunload_handler = true; + settings.accept_before_unload_dialog = true; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_TRUE(handler->got_do_close_); + EXPECT_TRUE(handler->got_before_close_); + EXPECT_TRUE(handler->got_before_unload_dialog_); + EXPECT_TRUE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_FALSE(handler->got_delay_close_); +} + +TEST(LifeSpanTest, OnUnloadDisallow) { + LifeSpanTestHandler::Settings settings; + settings.add_onunload_handler = true; + settings.accept_before_unload_dialog = false; + CefRefPtr handler = new LifeSpanTestHandler(settings); + handler->ExecuteTest(); + + EXPECT_TRUE(handler->got_after_created_); + EXPECT_FALSE(handler->got_do_close_); + EXPECT_FALSE(handler->got_before_close_); + EXPECT_TRUE(handler->got_before_unload_dialog_); + EXPECT_FALSE(handler->got_unload_message_); + EXPECT_TRUE(handler->got_load_end_); + EXPECT_TRUE(handler->got_delay_close_); +} diff --git a/tests/unittests/os_rendering_unittest_mac.h b/tests/unittests/os_rendering_unittest_mac.h index 8f047be33..e1df01d1a 100644 --- a/tests/unittests/os_rendering_unittest_mac.h +++ b/tests/unittests/os_rendering_unittest_mac.h @@ -1,18 +1,18 @@ -// Copyright (c) 2013 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 CEF_TESTS_UNITTESTS_OS_RENDERING_UNITTEST_MAC_H_ -#define CEF_TESTS_UNITTESTS_OS_RENDERING_UNITTEST_MAC_H_ - -#include "include/cef_base.h" -#include "ui/events/keycodes/keyboard_codes.h" - -namespace osr_unittests { - -CefWindowHandle GetFakeView(); -void GetKeyEvent(CefKeyEvent& event, ui::KeyboardCode keyCode, int modifiers); - -} // namespace osr_unittests - -#endif +// Copyright (c) 2013 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 CEF_TESTS_UNITTESTS_OS_RENDERING_UNITTEST_MAC_H_ +#define CEF_TESTS_UNITTESTS_OS_RENDERING_UNITTEST_MAC_H_ + +#include "include/cef_base.h" +#include "ui/events/keycodes/keyboard_codes.h" + +namespace osr_unittests { + +CefWindowHandle GetFakeView(); +void GetKeyEvent(CefKeyEvent& event, ui::KeyboardCode keyCode, int modifiers); + +} // namespace osr_unittests + +#endif diff --git a/tests/unittests/os_rendering_unittest_mac.mm b/tests/unittests/os_rendering_unittest_mac.mm index 821edbd1a..1b39bf097 100644 --- a/tests/unittests/os_rendering_unittest_mac.mm +++ b/tests/unittests/os_rendering_unittest_mac.mm @@ -1,39 +1,39 @@ -// Copyright (c) 2013 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. - -#import -#import - -#include "os_rendering_unittest_mac.h" - -#include "ui/events/keycodes/keyboard_code_conversion_mac.h" - -#include "include/cef_base.h" - -namespace osr_unittests { - -CefWindowHandle GetFakeView() { - NSScreen *mainScreen = [NSScreen mainScreen]; - NSRect screenRect = [mainScreen visibleFrame]; - NSView* fakeView = [[NSView alloc] initWithFrame: screenRect]; - return fakeView; -} - -void GetKeyEvent(CefKeyEvent& event, ui::KeyboardCode keyCode, int modifiers) { - unichar character; - unichar unmodified_character; - - // TODO(port): translate modifiers from the input format to NSFlags - // MacKeyCodeForWindowsKeyCode takes a NSUinteger as flags. - int macKeyCode = ui::MacKeyCodeForWindowsKeyCode(keyCode, - modifiers, - &character, - &unmodified_character); - - event.native_key_code = macKeyCode; - event.character = character; - event.unmodified_character = unmodified_character; -} - -} // namespace osr_unittests +// Copyright (c) 2013 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. + +#import +#import + +#include "os_rendering_unittest_mac.h" + +#include "ui/events/keycodes/keyboard_code_conversion_mac.h" + +#include "include/cef_base.h" + +namespace osr_unittests { + +CefWindowHandle GetFakeView() { + NSScreen *mainScreen = [NSScreen mainScreen]; + NSRect screenRect = [mainScreen visibleFrame]; + NSView* fakeView = [[NSView alloc] initWithFrame: screenRect]; + return fakeView; +} + +void GetKeyEvent(CefKeyEvent& event, ui::KeyboardCode keyCode, int modifiers) { + unichar character; + unichar unmodified_character; + + // TODO(port): translate modifiers from the input format to NSFlags + // MacKeyCodeForWindowsKeyCode takes a NSUinteger as flags. + int macKeyCode = ui::MacKeyCodeForWindowsKeyCode(keyCode, + modifiers, + &character, + &unmodified_character); + + event.native_key_code = macKeyCode; + event.character = character; + event.unmodified_character = unmodified_character; +} + +} // namespace osr_unittests diff --git a/tools/cef_api_hash.py b/tools/cef_api_hash.py index 2b720cd3f..36c71010a 100644 --- a/tools/cef_api_hash.py +++ b/tools/cef_api_hash.py @@ -1,246 +1,246 @@ -# Copyright (c) 2013 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. - -from file_util import * -import os -import re -import shutil -import string -import sys -import textwrap -import time -import itertools -import hashlib - - -class cef_api_hash: - """ CEF API hash calculator """ - - def __init__(self, headerdir, debugdir = None, verbose = False): - if headerdir is None or len(headerdir) == 0: - raise AssertionError("headerdir is not specified") - - self.__headerdir = headerdir; - self.__debugdir = debugdir; - self.__verbose = verbose; - self.__debug_enabled = not (self.__debugdir is None) and len(self.__debugdir) > 0; - - self.platforms = [ "windows", "macosx", "linux" ]; - - self.platform_files = { - "windows": [ - "internal/cef_types_win.h" - ], - "macosx": [ - "internal/cef_types_mac.h", - ], - "linux": [ - "internal/cef_types_linux.h" - ] - }; - - self.included_files = [ - "cef_trace_event.h" - ]; - - self.excluded_files = [ - "cef_version.h", - "internal/cef_tuple.h", - "internal/cef_types_wrappers.h", - "internal/cef_string_wrappers.h", - "internal/cef_win.h", - "internal/cef_mac.h", - "internal/cef_linux.h", - ]; - - def calculate(self): - filenames = [filename for filename in self.__get_filenames() if not filename in self.excluded_files] - - objects = [] - for filename in filenames: - if self.__verbose: - print "Processing " + filename + "..." - content = read_file(os.path.join(self.__headerdir, filename), True) - platforms = list([p for p in self.platforms if self.__is_platform_filename(filename, p)]) - - # Parse cef_string.h happens in special case: grab only defined CEF_STRING_TYPE_xxx declaration - content_objects = None - if filename == "internal/cef_string.h": - content_objects = self.__parse_string_type(content) - else: - content_objects = self.__parse_objects(content) - - for o in content_objects: - o["text"] = self.__prepare_text(o["text"]) - o["platforms"] = platforms - o["filename"] = filename - objects.append(o) - - # objects will be sorted including filename, to make stable universal hashes - objects = sorted(objects, key = lambda o: o["name"] + "@" + o["filename"]) - - if self.__debug_enabled: - namelen = max([len(o["name"]) for o in objects]) - filenamelen = max([len(o["filename"]) for o in objects]) - dumpsig = []; - for o in objects: - dumpsig.append(format(o["name"], str(namelen) + "s") + "|" + format(o["filename"], "" + str(filenamelen) + "s") + "|" + o["text"]); - self.__write_debug_file("objects.txt", dumpsig) - - revisions = { }; - - for platform in itertools.chain(["universal"], self.platforms): - sig = self.__get_final_sig(objects, platform) - if self.__debug_enabled: - self.__write_debug_file(platform + ".sig", sig) - rev = hashlib.sha1(sig).digest(); - revstr = ''.join(format(ord(i),'0>2x') for i in rev) - revisions[platform] = revstr - - return revisions - - def __parse_objects(self, content): - """ Returns array of objects in content file. """ - objects = [] - content = re.sub("//.*\n", "", content) - - # function declarations - for m in re.finditer("\nCEF_EXPORT\s+?.*?\s+?(\w+)\s*?\(.*?\)\s*?;", content, flags = re.DOTALL): - object = { - "name": m.group(1), - "text": m.group(0).strip() - } - objects.append(object) - - # structs - for m in re.finditer("\ntypedef\s+?struct\s+?(\w+)\s+?\{.*?\}\s+?(\w+)\s*?;", content, flags = re.DOTALL): - object = { - "name": m.group(2), - "text": m.group(0).strip() - } - objects.append(object) - - # enums - for m in re.finditer("\nenum\s+?(\w+)\s+?\{.*?\}\s*?;", content, flags = re.DOTALL): - object = { - "name": m.group(1), - "text": m.group(0).strip() - } - objects.append(object) - - # typedefs - for m in re.finditer("\ntypedef\s+?.*?\s+(\w+);", content, flags = 0): - object = { - "name": m.group(1), - "text": m.group(0).strip() - } - objects.append(object) - - return objects - - def __parse_string_type(self, content): - """ Grab defined CEF_STRING_TYPE_xxx """ - objects = [] - for m in re.finditer("\n\s*?#\s*?define\s+?(CEF_STRING_TYPE_\w+)\s+?.*?\n", content, flags = 0): - object = { - "name": m.group(1), - "text": m.group(0), - } - objects.append(object) - return objects - - def __prepare_text(self, text): - text = text.strip() - text = re.sub("\s+", " ", text); - text = re.sub("\(\s+", "(", text); - return text - - def __get_final_sig(self, objects, platform): - sig = [] - - for o in objects: - if platform == "universal" or platform in o["platforms"]: - sig.append(o["text"]) - - return "\n".join(sig) - - def __get_filenames(self): - """ Returns file names to be processed, relative to headerdir """ - headers = [os.path.join(self.__headerdir, filename) for filename in self.included_files]; - headers = itertools.chain(headers, get_files(os.path.join(self.__headerdir, "capi", "*.h"))) - headers = itertools.chain(headers, get_files(os.path.join(self.__headerdir, "internal", "*.h"))) - - for v in self.platform_files.values(): - headers = itertools.chain(headers, [os.path.join(self.__headerdir, f) for f in v]) - - normalized = [os.path.relpath(filename, self.__headerdir) for filename in headers]; - normalized = [f.replace('\\', '/').lower() for f in normalized]; - - return list(set(normalized)); - - def __is_platform_filename(self, filename, platform): - if platform == "universal": - return True - if not platform in self.platform_files: - return False - listed = False - for p in self.platforms: - if filename in self.platform_files[p]: - if p == platform: - return True - else: - listed = True - return not listed - - def __write_debug_file(self, filename, content): - make_dir(self.__debugdir); - outfile = os.path.join(self.__debugdir, filename); - dir = os.path.dirname(outfile); - make_dir(dir); - if not isinstance(content, basestring): - content = "\n".join(content) - write_file(outfile, content) - - -if __name__ == "__main__": - from optparse import OptionParser - import time - - disc = """ - This utility calculates CEF API hash. - """ - - parser = OptionParser(description=disc) - parser.add_option('--cpp-header-dir', dest='cppheaderdir', metavar='DIR', - help='input directory for C++ header files [required]') - parser.add_option('--debug-dir', dest='debugdir', metavar='DIR', - help='intermediate directory for easy debugging') - parser.add_option('-v', '--verbose', - action='store_true', dest='verbose', default=False, - help='output detailed status information') - (options, args) = parser.parse_args() - - # the cppheader option is required - if options.cppheaderdir is None: - parser.print_help(sys.stdout) - sys.exit() - - # calculate - c_start_time = time.time() - - calc = cef_api_hash(options.cppheaderdir, options.debugdir, options.verbose); - revisions = calc.calculate(); - - c_completed_in = time.time() - c_start_time - - print "{" - for k in sorted(revisions.keys()): - print format("\"" + k + "\"", ">12s") + ": \"" + revisions[k] + "\"" - print "}" - # print - # print 'Completed in: ' + str(c_completed_in) - # print - - # print "Press any key to continue..."; - # sys.stdin.readline(); +# Copyright (c) 2013 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. + +from file_util import * +import os +import re +import shutil +import string +import sys +import textwrap +import time +import itertools +import hashlib + + +class cef_api_hash: + """ CEF API hash calculator """ + + def __init__(self, headerdir, debugdir = None, verbose = False): + if headerdir is None or len(headerdir) == 0: + raise AssertionError("headerdir is not specified") + + self.__headerdir = headerdir; + self.__debugdir = debugdir; + self.__verbose = verbose; + self.__debug_enabled = not (self.__debugdir is None) and len(self.__debugdir) > 0; + + self.platforms = [ "windows", "macosx", "linux" ]; + + self.platform_files = { + "windows": [ + "internal/cef_types_win.h" + ], + "macosx": [ + "internal/cef_types_mac.h", + ], + "linux": [ + "internal/cef_types_linux.h" + ] + }; + + self.included_files = [ + "cef_trace_event.h" + ]; + + self.excluded_files = [ + "cef_version.h", + "internal/cef_tuple.h", + "internal/cef_types_wrappers.h", + "internal/cef_string_wrappers.h", + "internal/cef_win.h", + "internal/cef_mac.h", + "internal/cef_linux.h", + ]; + + def calculate(self): + filenames = [filename for filename in self.__get_filenames() if not filename in self.excluded_files] + + objects = [] + for filename in filenames: + if self.__verbose: + print "Processing " + filename + "..." + content = read_file(os.path.join(self.__headerdir, filename), True) + platforms = list([p for p in self.platforms if self.__is_platform_filename(filename, p)]) + + # Parse cef_string.h happens in special case: grab only defined CEF_STRING_TYPE_xxx declaration + content_objects = None + if filename == "internal/cef_string.h": + content_objects = self.__parse_string_type(content) + else: + content_objects = self.__parse_objects(content) + + for o in content_objects: + o["text"] = self.__prepare_text(o["text"]) + o["platforms"] = platforms + o["filename"] = filename + objects.append(o) + + # objects will be sorted including filename, to make stable universal hashes + objects = sorted(objects, key = lambda o: o["name"] + "@" + o["filename"]) + + if self.__debug_enabled: + namelen = max([len(o["name"]) for o in objects]) + filenamelen = max([len(o["filename"]) for o in objects]) + dumpsig = []; + for o in objects: + dumpsig.append(format(o["name"], str(namelen) + "s") + "|" + format(o["filename"], "" + str(filenamelen) + "s") + "|" + o["text"]); + self.__write_debug_file("objects.txt", dumpsig) + + revisions = { }; + + for platform in itertools.chain(["universal"], self.platforms): + sig = self.__get_final_sig(objects, platform) + if self.__debug_enabled: + self.__write_debug_file(platform + ".sig", sig) + rev = hashlib.sha1(sig).digest(); + revstr = ''.join(format(ord(i),'0>2x') for i in rev) + revisions[platform] = revstr + + return revisions + + def __parse_objects(self, content): + """ Returns array of objects in content file. """ + objects = [] + content = re.sub("//.*\n", "", content) + + # function declarations + for m in re.finditer("\nCEF_EXPORT\s+?.*?\s+?(\w+)\s*?\(.*?\)\s*?;", content, flags = re.DOTALL): + object = { + "name": m.group(1), + "text": m.group(0).strip() + } + objects.append(object) + + # structs + for m in re.finditer("\ntypedef\s+?struct\s+?(\w+)\s+?\{.*?\}\s+?(\w+)\s*?;", content, flags = re.DOTALL): + object = { + "name": m.group(2), + "text": m.group(0).strip() + } + objects.append(object) + + # enums + for m in re.finditer("\nenum\s+?(\w+)\s+?\{.*?\}\s*?;", content, flags = re.DOTALL): + object = { + "name": m.group(1), + "text": m.group(0).strip() + } + objects.append(object) + + # typedefs + for m in re.finditer("\ntypedef\s+?.*?\s+(\w+);", content, flags = 0): + object = { + "name": m.group(1), + "text": m.group(0).strip() + } + objects.append(object) + + return objects + + def __parse_string_type(self, content): + """ Grab defined CEF_STRING_TYPE_xxx """ + objects = [] + for m in re.finditer("\n\s*?#\s*?define\s+?(CEF_STRING_TYPE_\w+)\s+?.*?\n", content, flags = 0): + object = { + "name": m.group(1), + "text": m.group(0), + } + objects.append(object) + return objects + + def __prepare_text(self, text): + text = text.strip() + text = re.sub("\s+", " ", text); + text = re.sub("\(\s+", "(", text); + return text + + def __get_final_sig(self, objects, platform): + sig = [] + + for o in objects: + if platform == "universal" or platform in o["platforms"]: + sig.append(o["text"]) + + return "\n".join(sig) + + def __get_filenames(self): + """ Returns file names to be processed, relative to headerdir """ + headers = [os.path.join(self.__headerdir, filename) for filename in self.included_files]; + headers = itertools.chain(headers, get_files(os.path.join(self.__headerdir, "capi", "*.h"))) + headers = itertools.chain(headers, get_files(os.path.join(self.__headerdir, "internal", "*.h"))) + + for v in self.platform_files.values(): + headers = itertools.chain(headers, [os.path.join(self.__headerdir, f) for f in v]) + + normalized = [os.path.relpath(filename, self.__headerdir) for filename in headers]; + normalized = [f.replace('\\', '/').lower() for f in normalized]; + + return list(set(normalized)); + + def __is_platform_filename(self, filename, platform): + if platform == "universal": + return True + if not platform in self.platform_files: + return False + listed = False + for p in self.platforms: + if filename in self.platform_files[p]: + if p == platform: + return True + else: + listed = True + return not listed + + def __write_debug_file(self, filename, content): + make_dir(self.__debugdir); + outfile = os.path.join(self.__debugdir, filename); + dir = os.path.dirname(outfile); + make_dir(dir); + if not isinstance(content, basestring): + content = "\n".join(content) + write_file(outfile, content) + + +if __name__ == "__main__": + from optparse import OptionParser + import time + + disc = """ + This utility calculates CEF API hash. + """ + + parser = OptionParser(description=disc) + parser.add_option('--cpp-header-dir', dest='cppheaderdir', metavar='DIR', + help='input directory for C++ header files [required]') + parser.add_option('--debug-dir', dest='debugdir', metavar='DIR', + help='intermediate directory for easy debugging') + parser.add_option('-v', '--verbose', + action='store_true', dest='verbose', default=False, + help='output detailed status information') + (options, args) = parser.parse_args() + + # the cppheader option is required + if options.cppheaderdir is None: + parser.print_help(sys.stdout) + sys.exit() + + # calculate + c_start_time = time.time() + + calc = cef_api_hash(options.cppheaderdir, options.debugdir, options.verbose); + revisions = calc.calculate(); + + c_completed_in = time.time() - c_start_time + + print "{" + for k in sorted(revisions.keys()): + print format("\"" + k + "\"", ">12s") + ": \"" + revisions[k] + "\"" + print "}" + # print + # print 'Completed in: ' + str(c_completed_in) + # print + + # print "Press any key to continue..."; + # sys.stdin.readline(); diff --git a/tools/date_util.py b/tools/date_util.py index c19af17b4..ca447f309 100644 --- a/tools/date_util.py +++ b/tools/date_util.py @@ -1,13 +1,13 @@ -# Copyright (c) 2011 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. - -import datetime - -def get_year(): - """ Returns the current year. """ - return str(datetime.datetime.now().year) - -def get_date(): - """ Returns the current date. """ - return datetime.datetime.now().strftime('%B %d, %Y') +# Copyright (c) 2011 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. + +import datetime + +def get_year(): + """ Returns the current year. """ + return str(datetime.datetime.now().year) + +def get_date(): + """ Returns the current date. """ + return datetime.datetime.now().strftime('%B %d, %Y') diff --git a/tools/make_distrib.py b/tools/make_distrib.py index fc745ba01..251e24f6d 100644 --- a/tools/make_distrib.py +++ b/tools/make_distrib.py @@ -1,713 +1,713 @@ -# Copyright (c) 2011 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. - -from date_util import * -from file_util import * -from gclient_util import * -from optparse import OptionParser -import os -import re -import shlex -import subprocess -from svn_util import * -import sys -import zipfile - -def create_archive(input_dir, zip_file): - """ Creates a zip archive of the specified input directory. """ - zf = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) - def addDir(dir): - for f in os.listdir(dir): - full_path = os.path.join(dir, f) - if os.path.isdir(full_path): - addDir(full_path) - else: - zf.write(full_path, os.path.relpath(full_path, \ - os.path.join(input_dir, os.pardir))) - addDir(input_dir) - zf.close() - -def create_7z_archive(input_dir, zip_file): - """ Creates a 7z archive of the specified input directory. """ - command = os.environ['CEF_COMMAND_7ZIP'] - run('"' + command + '" a -y ' + zip_file + ' ' + input_dir, os.path.split(zip_file)[0]) - -def create_output_dir(name, parent_dir): - """ Creates an output directory and adds the path to the archive list. """ - output_dir = os.path.abspath(os.path.join(parent_dir, name)) - remove_dir(output_dir, options.quiet) - make_dir(output_dir, options.quiet) - archive_dirs.append(output_dir) - return output_dir - -def get_readme_component(name): - """ Loads a README file component. """ - paths = [] - # platform directory - if platform == 'windows': - platform_cmp = 'win' - elif platform == 'macosx': - platform_cmp = 'mac' - elif platform == 'linux': - platform_cmp = 'linux' - paths.append(os.path.join(script_dir, 'distrib', platform_cmp)) - - # shared directory - paths.append(os.path.join(script_dir, 'distrib')) - - # load the file if it exists - for path in paths: - file = os.path.join(path, 'README.' +name + '.txt') - if path_exists(file): - return read_file(file) - - raise Exception('Readme component not found: ' + name) - -def create_readme(): - """ Creates the README.TXT file. """ - # gather the components - header_data = get_readme_component('header') - mode_data = get_readme_component(mode) - redistrib_data = get_readme_component('redistrib') - footer_data = get_readme_component('footer') - - # format the file - data = header_data + '\n\n' + mode_data + '\n\n' + redistrib_data + '\n\n' + footer_data - data = data.replace('$CEF_URL$', cef_url) - data = data.replace('$CEF_REV$', cef_rev) - data = data.replace('$CEF_VER$', cef_ver) - data = data.replace('$CHROMIUM_URL$', chromium_url) - data = data.replace('$CHROMIUM_REV$', chromium_rev) - data = data.replace('$CHROMIUM_VER$', chromium_ver) - data = data.replace('$DATE$', date) - - if platform == 'windows': - platform_str = 'Windows' - elif platform == 'macosx': - platform_str = 'Mac OS-X' - elif platform == 'linux': - platform_str = 'Linux' - - data = data.replace('$PLATFORM$', platform_str) - - if mode == 'standard': - distrib_type = 'Standard' - distrib_desc = 'This distribution contains all components necessary to build and distribute an\n' \ - 'application using CEF on the ' + platform_str + ' platform. Please see the LICENSING\n' \ - 'section of this document for licensing terms and conditions.' - elif mode == 'minimal': - distrib_type = 'Minimal' - distrib_desc = 'This distribution contains only the components required to distribute an\n' \ - 'application using CEF on the ' + platform_str + ' platform. Please see the LICENSING\n' \ - 'section of this document for licensing terms and conditions.' - elif mode == 'client': - distrib_type = 'Client' - distrib_desc = 'This distribution contains a release build of the cefclient sample application\n' \ - 'for the ' + platform_str + ' platform. Please see the LICENSING section of this document for\n' \ - 'licensing terms and conditions.' - - data = data.replace('$DISTRIB_TYPE$', distrib_type) - data = data.replace('$DISTRIB_DESC$', distrib_desc) - - write_file(os.path.join(output_dir, 'README.txt'), data) - if not options.quiet: - sys.stdout.write('Creating README.TXT file.\n') - -def eval_file(src): - """ Loads and evaluates the contents of the specified file. """ - return eval(read_file(src), {'__builtins__': None}, None) - -def transfer_gypi_files(src_dir, gypi_paths, gypi_path_prefix, dst_dir, quiet): - """ Transfer files from one location to another. """ - for path in gypi_paths: - # skip gyp includes - if path[:2] == '<@': - continue - src = os.path.join(src_dir, path) - dst = os.path.join(dst_dir, path.replace(gypi_path_prefix, '')) - dst_path = os.path.dirname(dst) - make_dir(dst_path, quiet) - copy_file(src, dst, quiet) - -def normalize_headers(file, new_path = ''): - """ Normalize headers post-processing. Remove the path component from any - project include directives. """ - data = read_file(file) - data = re.sub(r'''#include \"(?!include\/)[a-zA-Z0-9_\/]+\/+([a-zA-Z0-9_\.]+)\"''', \ - "// Include path modified for CEF Binary Distribution.\n#include \""+new_path+"\\1\"", data) - write_file(file, data) - -def transfer_files(cef_dir, script_dir, transfer_cfg, output_dir, quiet): - """ Transfer files based on the specified configuration. """ - if not path_exists(transfer_cfg): - return - - configs = eval_file(transfer_cfg) - for cfg in configs: - dst = os.path.join(output_dir, cfg['target']) - - # perform a copy if source is specified - if not cfg['source'] is None: - src = os.path.join(cef_dir, cfg['source']) - dst_path = os.path.dirname(dst) - make_dir(dst_path, quiet) - copy_file(src, dst, quiet) - - # place a readme file in the destination directory - readme = os.path.join(dst_path, 'README-TRANSFER.txt') - if not path_exists(readme): - copy_file(os.path.join(script_dir, 'distrib/README-TRANSFER.txt'), readme) - open(readme, 'ab').write(cfg['source']+"\n") - - # perform any required post-processing - if 'post-process' in cfg: - post = cfg['post-process'] - if post == 'normalize_headers': - new_path = '' - if cfg.has_key('new_header_path'): - new_path = cfg['new_header_path'] - normalize_headers(dst, new_path) - -def generate_msvs_projects(version): - """ Generate MSVS projects for the specified version. """ - sys.stdout.write('Generating '+version+' project files...') - os.environ['GYP_GENERATORS'] = 'msvs' - os.environ['GYP_MSVS_VERSION'] = version - gyper = [ 'python', 'tools/gyp_cef', os.path.relpath(os.path.join(output_dir, 'cefclient.gyp'), cef_dir) ] - RunAction(cef_dir, gyper); - move_file(os.path.relpath(os.path.join(output_dir, 'cefclient.sln')), \ - os.path.relpath(os.path.join(output_dir, 'cefclient'+version+'.sln'))) - -def create_msvs_projects(): - """ Create MSVS project files. """ - if not options.x64build: - generate_msvs_projects('2005'); - generate_msvs_projects('2008'); - generate_msvs_projects('2010'); - - # Fix the output directory path in all .vcproj and .vcxproj files. - files = [] - for file in get_files(os.path.join(output_dir, '*.vcproj')): - files.append(file) - for file in get_files(os.path.join(output_dir, '*.vcxproj')): - files.append(file) - for file in files: - data = read_file(file) - # fix the build directory path - data = data.replace('../../..\\build\\', 'out\\') - data = data.replace('..\\..\\..\\build\\', 'out\\') - # fix xcopy arguments - data = data.replace('xcopy \\', 'xcopy /') - if options.x64build: - # fix machine type - data = data.replace('MachineX86', 'MachineX64') - write_file(file, data) - -def create_xcode_projects(): - """ Create Xcode project files. """ - sys.stdout.write('Generating Xcode project files...') - os.environ['GYP_GENERATORS'] = 'xcode' - gyper = [ 'python', 'tools/gyp_cef', os.path.relpath(os.path.join(output_dir, 'cefclient.gyp'), cef_dir) ] - RunAction(cef_dir, gyper); - - # Post-process the Xcode project to fix file paths - src_file = os.path.join(output_dir, 'cefclient.xcodeproj/project.pbxproj') - data = read_file(src_file) - data = data.replace('../../../build/mac/', 'tools/') - data = data.replace('../../../build', 'build') - data = data.replace('../../../xcodebuild', 'xcodebuild') - write_file(src_file, data) - -def create_make_projects(): - """ Create make project files. """ - makefile = os.path.join(src_dir, 'Makefile') - makefile_tmp = '' - if path_exists(makefile): - # Back up the existing Makefile - makefile_tmp = makefile + '.cef_bak' - copy_file(makefile, makefile_tmp, options.quiet) - - # Generate make project files - sys.stdout.write('Generating make project files...') - os.environ['GYP_GENERATORS'] = 'make' - gyper = [ 'python', 'tools/gyp_cef', os.path.relpath(os.path.join(output_dir, 'cefclient.gyp'), cef_dir) ] - RunAction(cef_dir, gyper); - - # Copy the resulting Makefile to the destination directory - copy_file(makefile, output_dir, options.quiet) - - remove_file(makefile, options.quiet) - if makefile_tmp != '': - # Restore the original Makefile - move_file(makefile_tmp, makefile, options.quiet) - - # Fix the output directory path in Makefile and all .mk files. - find = os.path.relpath(output_dir, src_dir) - files = [os.path.join(output_dir, 'Makefile')] - for file in get_files(os.path.join(output_dir, '*.mk')): - files.append(file) - for file in files: - data = read_file(file) - data = data.replace(find, '.') - data = data.replace('/./', '/') - if os.path.basename(file) == 'Makefile': - # remove the quiet_cmd_regen_makefile section - pos = str.find(data, 'quiet_cmd_regen_makefile') - if pos >= 0: - epos = str.find(data, '#', pos) - if epos >= 0: - data = data[0:pos] + data[epos:] - write_file(file, data) - -def run(command_line, working_dir): - """ Run a command. """ - sys.stdout.write('-------- Running "'+command_line+'" in "'+\ - working_dir+'"...'+"\n") - args = shlex.split(command_line.replace('\\', '\\\\')) - return subprocess.check_call(args, cwd=working_dir, env=os.environ, - shell=(sys.platform == 'win32')) - -# cannot be loaded as a module -if __name__ != "__main__": - sys.stderr.write('This file cannot be loaded as a module!') - sys.exit() - -# parse command-line options -disc = """ -This utility builds the CEF Binary Distribution. -""" - -parser = OptionParser(description=disc) -parser.add_option('--output-dir', dest='outputdir', metavar='DIR', - help='output directory [required]') -parser.add_option('--allow-partial', - action='store_true', dest='allowpartial', default=False, - help='allow creation of partial distributions') -parser.add_option('--no-symbols', - action='store_true', dest='nosymbols', default=False, - help='don\'t create symbol files') -parser.add_option('--no-docs', - action='store_true', dest='nodocs', default=False, - help='don\'t create documentation') -parser.add_option('--no-archive', - action='store_true', dest='noarchive', default=False, - help='don\'t create archives for output directories') -parser.add_option('--ninja-build', - action='store_true', dest='ninjabuild', default=False, - help='build was created using ninja') -parser.add_option('--x64-build', - action='store_true', dest='x64build', default=False, - help='build was created for 64-bit systems') -parser.add_option('--minimal', - action='store_true', dest='minimal', default=False, - help='include only release build binary files') -parser.add_option('--client', - action='store_true', dest='client', default=False, - help='include only the cefclient application') -parser.add_option('-q', '--quiet', - action='store_true', dest='quiet', default=False, - help='do not output detailed status information') -(options, args) = parser.parse_args() - -# Test the operating system. -platform = ''; -if sys.platform == 'win32': - platform = 'windows' -elif sys.platform == 'darwin': - platform = 'macosx' -elif sys.platform.startswith('linux'): - platform = 'linux' - -# the outputdir option is required -if options.outputdir is None: - parser.print_help(sys.stderr) - sys.exit() - -if options.minimal and options.client: - print 'Invalid combination of options' - parser.print_help(sys.stderr) - sys.exit() - -if platform == 'windows' and options.x64build and not options.ninjabuild: - print 'x64 build on Windows requires ninja' - sys.exit() - -# script directory -script_dir = os.path.dirname(__file__) - -# CEF root directory -cef_dir = os.path.abspath(os.path.join(script_dir, os.pardir)) - -# src directory -src_dir = os.path.abspath(os.path.join(cef_dir, os.pardir)) - -# retrieve url, revision and date information -cef_info = get_svn_info(cef_dir) -cef_url = cef_info['url'] -cef_rev = cef_info['revision'] -chromium_info = get_svn_info(os.path.join(cef_dir, os.pardir)) -chromium_url = chromium_info['url'] -chromium_rev = chromium_info['revision'] -date = get_date() - -# Read and parse the version file (key=value pairs, one per line) -args = {} -read_version_file(os.path.join(cef_dir, 'VERSION'), args) -read_version_file(os.path.join(cef_dir, '../chrome/VERSION'), args) - -cef_ver = args['CEF_MAJOR']+'.'+args['BUILD']+'.'+cef_rev -chromium_ver = args['MAJOR']+'.'+args['MINOR']+'.'+args['BUILD']+'.'+args['PATCH'] - -# list of output directories to be archived -archive_dirs = [] - -platform_arch = '32' -if options.x64build: - platform_arch = '64' - -if platform == 'linux': - platform_arch = '' - lib_dir_name = 'lib.target' - if options.ninjabuild: - lib_dir_name = 'lib' - release_libcef_path = os.path.join(src_dir, 'out', 'Release', lib_dir_name, 'libcef.so'); - debug_libcef_path = os.path.join(src_dir, 'out', 'Debug', lib_dir_name, 'libcef.so'); - file_desc = '' - output = subprocess.check_output('file ' + release_libcef_path + ' ' + debug_libcef_path + '; exit 0', - env=os.environ, stderr=subprocess.STDOUT, shell=True) - if output.find('32-bit') != -1: - platform_arch = '32' - if output.find('64-bit') != -1: - platform_arch = '64' - -# output directory -output_dir_base = 'cef_binary_' + cef_ver -output_dir_name = output_dir_base + '_' + platform + platform_arch - -if options.minimal: - mode = 'minimal' - output_dir_name = output_dir_name + '_minimal' -elif options.client: - mode = 'client' - output_dir_name = output_dir_name + '_client' -else: - mode = 'standard' - -output_dir = create_output_dir(output_dir_name, options.outputdir) - -# create the README.TXT file -create_readme() - -# transfer the LICENSE.txt file -copy_file(os.path.join(cef_dir, 'LICENSE.txt'), output_dir, options.quiet) - -# read the variables list from the autogenerated cef_paths.gypi file -cef_paths = eval_file(os.path.join(cef_dir, 'cef_paths.gypi')) -cef_paths = cef_paths['variables'] - -# read the variables list from the manually edited cef_paths2.gypi file -cef_paths2 = eval_file(os.path.join(cef_dir, 'cef_paths2.gypi')) -cef_paths2 = cef_paths2['variables'] - -if mode == 'standard': - # create the include directory - include_dir = os.path.join(output_dir, 'include') - make_dir(include_dir, options.quiet) - - # create the cefclient directory - cefclient_dir = os.path.join(output_dir, 'cefclient') - make_dir(cefclient_dir, options.quiet) - - # create the libcef_dll_wrapper directory - wrapper_dir = os.path.join(output_dir, 'libcef_dll') - make_dir(wrapper_dir, options.quiet) - - # transfer common include files - transfer_gypi_files(cef_dir, cef_paths2['includes_common'], \ - 'include/', include_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths2['includes_capi'], \ - 'include/', include_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths2['includes_wrapper'], \ - 'include/', include_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths['autogen_cpp_includes'], \ - 'include/', include_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths['autogen_capi_includes'], \ - 'include/', include_dir, options.quiet) - - # transfer common cefclient files - transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_common'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths2['cefclient_bundle_resources_common'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - - # transfer common libcef_dll_wrapper files - transfer_gypi_files(cef_dir, cef_paths2['libcef_dll_wrapper_sources_common'], \ - 'libcef_dll/', wrapper_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths['autogen_client_side'], \ - 'libcef_dll/', wrapper_dir, options.quiet) - - # transfer gyp files - copy_file(os.path.join(script_dir, 'distrib/cefclient.gyp'), output_dir, options.quiet) - paths_gypi = os.path.join(cef_dir, 'cef_paths2.gypi') - data = read_file(paths_gypi) - data = data.replace('tests/cefclient/', 'cefclient/') - write_file(os.path.join(output_dir, 'cef_paths2.gypi'), data) - copy_file(os.path.join(cef_dir, 'cef_paths.gypi'), \ - os.path.join(output_dir, 'cef_paths.gypi'), options.quiet) - - # transfer additional files - transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/transfer.cfg'), \ - output_dir, options.quiet) - -if platform == 'windows': - if options.ninjabuild: - out_dir = os.path.join(src_dir, 'out') - libcef_dll_file = 'libcef.dll.lib' - else: - out_dir = os.path.join(src_dir, 'build') - libcef_dll_file = 'lib/libcef.lib' - - valid_build_dir = None - - build_dir_suffix = '' - if options.x64build: - build_dir_suffix = '_x64' - - if mode == 'standard': - # transfer Debug files - build_dir = os.path.join(out_dir, 'Debug' + build_dir_suffix); - if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.exe')): - valid_build_dir = build_dir - dst_dir = os.path.join(output_dir, 'Debug') - make_dir(dst_dir, options.quiet) - copy_files(os.path.join(script_dir, 'distrib/win/*.dll'), dst_dir, options.quiet) - copy_files(os.path.join(build_dir, '*.dll'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, libcef_dll_file), os.path.join(dst_dir, 'libcef.lib'), \ - options.quiet) - - if not options.nosymbols: - # create the symbol output directory - symbol_output_dir = create_output_dir(output_dir_name + '_debug_symbols', options.outputdir) - # transfer contents - copy_file(os.path.join(build_dir, 'libcef.dll.pdb'), symbol_output_dir, options.quiet) - else: - sys.stderr.write("No Debug build files.\n") - - # transfer Release files - build_dir = os.path.join(out_dir, 'Release' + build_dir_suffix); - if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.exe')): - valid_build_dir = build_dir - dst_dir = os.path.join(output_dir, 'Release') - make_dir(dst_dir, options.quiet) - copy_files(os.path.join(script_dir, 'distrib/win/*.dll'), dst_dir, options.quiet) - copy_files(os.path.join(build_dir, '*.dll'), dst_dir, options.quiet) - - if mode != 'client': - copy_file(os.path.join(build_dir, libcef_dll_file), os.path.join(dst_dir, 'libcef.lib'), \ - options.quiet) - else: - copy_file(os.path.join(build_dir, 'cefclient.exe'), dst_dir, options.quiet) - - if not options.nosymbols: - # create the symbol output directory - symbol_output_dir = create_output_dir(output_dir_name + '_release_symbols', options.outputdir) - # transfer contents - copy_file(os.path.join(build_dir, 'libcef.dll.pdb'), symbol_output_dir, options.quiet) - else: - sys.stderr.write("No Release build files.\n") - - if not valid_build_dir is None: - # transfer resource files - build_dir = valid_build_dir - if mode == 'client': - dst_dir = os.path.join(output_dir, 'Release') - else: - dst_dir = os.path.join(output_dir, 'Resources') - make_dir(dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'cef.pak'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'devtools_resources.pak'), dst_dir, options.quiet) - copy_dir(os.path.join(build_dir, 'locales'), os.path.join(dst_dir, 'locales'), options.quiet) - - if mode == 'standard': - # transfer include files - transfer_gypi_files(cef_dir, cef_paths2['includes_win'], \ - 'include/', include_dir, options.quiet) - - # transfer cefclient files - transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_win'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - - # transfer additional files, if any - transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/win/transfer.cfg'), \ - output_dir, options.quiet) - - create_msvs_projects() - - if not options.nodocs: - # generate doc files - os.popen('make_cppdocs.bat '+cef_rev) - - src_dir = os.path.join(cef_dir, 'docs') - if path_exists(src_dir): - # create the docs output directory - docs_output_dir = create_output_dir(output_dir_base + '_docs', options.outputdir) - # transfer contents - copy_dir(src_dir, docs_output_dir, options.quiet) - -elif platform == 'macosx': - if options.ninjabuild: - out_dir = os.path.join(src_dir, 'out') - else: - out_dir = os.path.join(src_dir, 'xcodebuild') - - valid_build_dir = None - - if mode == 'standard': - # transfer Debug files - build_dir = os.path.join(out_dir, 'Debug') - if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.app')): - valid_build_dir = build_dir - dst_dir = os.path.join(output_dir, 'Debug') - make_dir(dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'ffmpegsumo.so'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libcef.dylib'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libplugin_carbon_interpose.dylib'), dst_dir, options.quiet) - - # transfer Release files - build_dir = os.path.join(out_dir, 'Release') - if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.app')): - valid_build_dir = build_dir - dst_dir = os.path.join(output_dir, 'Release') - make_dir(dst_dir, options.quiet) - if mode != 'client': - copy_file(os.path.join(build_dir, 'ffmpegsumo.so'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libcef.dylib'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libplugin_carbon_interpose.dylib'), dst_dir, options.quiet) - else: - copy_dir(os.path.join(build_dir, 'cefclient.app'), os.path.join(dst_dir, 'cefclient.app'), options.quiet) - - if not options.nosymbols: - # create the symbol output directory - symbol_output_dir = create_output_dir(output_dir_name + '_release_symbols', options.outputdir) - - # create the real dSYM file from the "fake" dSYM file - sys.stdout.write("Creating the real dSYM file...\n") - src_path = os.path.join(build_dir, 'libcef.dylib.dSYM/Contents/Resources/DWARF/libcef.dylib') - dst_path = os.path.join(symbol_output_dir, 'libcef.dylib.dSYM') - run('dsymutil '+src_path+' -o '+dst_path, cef_dir) - - if not valid_build_dir is None and mode != 'client': - # transfer resource files - build_dir = valid_build_dir - dst_dir = os.path.join(output_dir, 'Resources') - make_dir(dst_dir, options.quiet) - copy_files(os.path.join(build_dir, 'cefclient.app/Contents/Frameworks/Chromium Embedded Framework.framework/Resources/*.*'), \ - dst_dir, options.quiet) - - if mode == 'standard': - # transfer include files - transfer_gypi_files(cef_dir, cef_paths2['includes_mac'], \ - 'include/', include_dir, options.quiet) - - # transfer cefclient files - transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_mac'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_mac_helper'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths2['cefclient_bundle_resources_mac'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - - # transfer cefclient/mac files - copy_dir(os.path.join(cef_dir, 'tests/cefclient/mac/'), os.path.join(output_dir, 'cefclient/mac/'), \ - options.quiet) - - # transfer additional files, if any - transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/mac/transfer.cfg'), \ - output_dir, options.quiet) - - create_xcode_projects() - -elif platform == 'linux': - out_dir = os.path.join(src_dir, 'out') - if options.ninjabuild: - lib_dir_name = 'lib' - else: - lib_dir_name = 'lib.target' - - valid_build_dir = None - - if mode == 'standard': - # transfer Debug files - build_dir = os.path.join(out_dir, 'Debug'); - if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient')): - valid_build_dir = build_dir - dst_dir = os.path.join(output_dir, 'Debug') - make_dir(dst_dir, options.quiet) - copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libffmpegsumo.so'), dst_dir, options.quiet) - else: - sys.stderr.write("No Debug build files.\n") - - # transfer Release files - build_dir = os.path.join(out_dir, 'Release'); - if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient')): - valid_build_dir = build_dir - dst_dir = os.path.join(output_dir, 'Release') - make_dir(dst_dir, options.quiet) - - if mode == 'client': - lib_dst_dir = os.path.join(dst_dir, lib_dir_name) - make_dir(lib_dst_dir, options.quiet) - copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), lib_dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'cefclient'), dst_dir, options.quiet) - else: - copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libffmpegsumo.so'), dst_dir, options.quiet) - else: - sys.stderr.write("No Release build files.\n") - - if not valid_build_dir is None: - # transfer resource files - build_dir = valid_build_dir - if mode == 'client': - dst_dir = os.path.join(output_dir, 'Release') - copy_dir(os.path.join(build_dir, 'files'), os.path.join(dst_dir, 'files'), options.quiet) - else: - dst_dir = os.path.join(output_dir, 'Resources') - make_dir(dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'cef.pak'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'devtools_resources.pak'), dst_dir, options.quiet) - copy_dir(os.path.join(build_dir, 'locales'), os.path.join(dst_dir, 'locales'), options.quiet) - - if mode == 'standard': - # transfer include files - transfer_gypi_files(cef_dir, cef_paths2['includes_linux'], \ - 'include/', include_dir, options.quiet) - - # transfer cefclient files - transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_linux'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - transfer_gypi_files(cef_dir, cef_paths2['cefclient_bundle_resources_linux'], \ - 'tests/cefclient/', cefclient_dir, options.quiet) - - # transfer additional files, if any - copy_file(os.path.join(script_dir, 'distrib/linux/build.sh'), output_dir, options.quiet) - transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/linux/transfer.cfg'), \ - output_dir, options.quiet) - - create_make_projects() - -if not options.noarchive: - # create an archive for each output directory - archive_extenstion = '.zip' - if os.getenv('CEF_COMMAND_7ZIP', '') != '': - archive_extenstion = '.7z' - for dir in archive_dirs: - zip_file = os.path.split(dir)[1] + archive_extenstion - if not options.quiet: - sys.stdout.write('Creating '+zip_file+"...\n") - if archive_extenstion == '.zip': - create_archive(dir, os.path.join(dir, os.pardir, zip_file)) - else: - create_7z_archive(dir, os.path.join(dir, os.pardir, zip_file)) +# Copyright (c) 2011 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. + +from date_util import * +from file_util import * +from gclient_util import * +from optparse import OptionParser +import os +import re +import shlex +import subprocess +from svn_util import * +import sys +import zipfile + +def create_archive(input_dir, zip_file): + """ Creates a zip archive of the specified input directory. """ + zf = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) + def addDir(dir): + for f in os.listdir(dir): + full_path = os.path.join(dir, f) + if os.path.isdir(full_path): + addDir(full_path) + else: + zf.write(full_path, os.path.relpath(full_path, \ + os.path.join(input_dir, os.pardir))) + addDir(input_dir) + zf.close() + +def create_7z_archive(input_dir, zip_file): + """ Creates a 7z archive of the specified input directory. """ + command = os.environ['CEF_COMMAND_7ZIP'] + run('"' + command + '" a -y ' + zip_file + ' ' + input_dir, os.path.split(zip_file)[0]) + +def create_output_dir(name, parent_dir): + """ Creates an output directory and adds the path to the archive list. """ + output_dir = os.path.abspath(os.path.join(parent_dir, name)) + remove_dir(output_dir, options.quiet) + make_dir(output_dir, options.quiet) + archive_dirs.append(output_dir) + return output_dir + +def get_readme_component(name): + """ Loads a README file component. """ + paths = [] + # platform directory + if platform == 'windows': + platform_cmp = 'win' + elif platform == 'macosx': + platform_cmp = 'mac' + elif platform == 'linux': + platform_cmp = 'linux' + paths.append(os.path.join(script_dir, 'distrib', platform_cmp)) + + # shared directory + paths.append(os.path.join(script_dir, 'distrib')) + + # load the file if it exists + for path in paths: + file = os.path.join(path, 'README.' +name + '.txt') + if path_exists(file): + return read_file(file) + + raise Exception('Readme component not found: ' + name) + +def create_readme(): + """ Creates the README.TXT file. """ + # gather the components + header_data = get_readme_component('header') + mode_data = get_readme_component(mode) + redistrib_data = get_readme_component('redistrib') + footer_data = get_readme_component('footer') + + # format the file + data = header_data + '\n\n' + mode_data + '\n\n' + redistrib_data + '\n\n' + footer_data + data = data.replace('$CEF_URL$', cef_url) + data = data.replace('$CEF_REV$', cef_rev) + data = data.replace('$CEF_VER$', cef_ver) + data = data.replace('$CHROMIUM_URL$', chromium_url) + data = data.replace('$CHROMIUM_REV$', chromium_rev) + data = data.replace('$CHROMIUM_VER$', chromium_ver) + data = data.replace('$DATE$', date) + + if platform == 'windows': + platform_str = 'Windows' + elif platform == 'macosx': + platform_str = 'Mac OS-X' + elif platform == 'linux': + platform_str = 'Linux' + + data = data.replace('$PLATFORM$', platform_str) + + if mode == 'standard': + distrib_type = 'Standard' + distrib_desc = 'This distribution contains all components necessary to build and distribute an\n' \ + 'application using CEF on the ' + platform_str + ' platform. Please see the LICENSING\n' \ + 'section of this document for licensing terms and conditions.' + elif mode == 'minimal': + distrib_type = 'Minimal' + distrib_desc = 'This distribution contains only the components required to distribute an\n' \ + 'application using CEF on the ' + platform_str + ' platform. Please see the LICENSING\n' \ + 'section of this document for licensing terms and conditions.' + elif mode == 'client': + distrib_type = 'Client' + distrib_desc = 'This distribution contains a release build of the cefclient sample application\n' \ + 'for the ' + platform_str + ' platform. Please see the LICENSING section of this document for\n' \ + 'licensing terms and conditions.' + + data = data.replace('$DISTRIB_TYPE$', distrib_type) + data = data.replace('$DISTRIB_DESC$', distrib_desc) + + write_file(os.path.join(output_dir, 'README.txt'), data) + if not options.quiet: + sys.stdout.write('Creating README.TXT file.\n') + +def eval_file(src): + """ Loads and evaluates the contents of the specified file. """ + return eval(read_file(src), {'__builtins__': None}, None) + +def transfer_gypi_files(src_dir, gypi_paths, gypi_path_prefix, dst_dir, quiet): + """ Transfer files from one location to another. """ + for path in gypi_paths: + # skip gyp includes + if path[:2] == '<@': + continue + src = os.path.join(src_dir, path) + dst = os.path.join(dst_dir, path.replace(gypi_path_prefix, '')) + dst_path = os.path.dirname(dst) + make_dir(dst_path, quiet) + copy_file(src, dst, quiet) + +def normalize_headers(file, new_path = ''): + """ Normalize headers post-processing. Remove the path component from any + project include directives. """ + data = read_file(file) + data = re.sub(r'''#include \"(?!include\/)[a-zA-Z0-9_\/]+\/+([a-zA-Z0-9_\.]+)\"''', \ + "// Include path modified for CEF Binary Distribution.\n#include \""+new_path+"\\1\"", data) + write_file(file, data) + +def transfer_files(cef_dir, script_dir, transfer_cfg, output_dir, quiet): + """ Transfer files based on the specified configuration. """ + if not path_exists(transfer_cfg): + return + + configs = eval_file(transfer_cfg) + for cfg in configs: + dst = os.path.join(output_dir, cfg['target']) + + # perform a copy if source is specified + if not cfg['source'] is None: + src = os.path.join(cef_dir, cfg['source']) + dst_path = os.path.dirname(dst) + make_dir(dst_path, quiet) + copy_file(src, dst, quiet) + + # place a readme file in the destination directory + readme = os.path.join(dst_path, 'README-TRANSFER.txt') + if not path_exists(readme): + copy_file(os.path.join(script_dir, 'distrib/README-TRANSFER.txt'), readme) + open(readme, 'ab').write(cfg['source']+"\n") + + # perform any required post-processing + if 'post-process' in cfg: + post = cfg['post-process'] + if post == 'normalize_headers': + new_path = '' + if cfg.has_key('new_header_path'): + new_path = cfg['new_header_path'] + normalize_headers(dst, new_path) + +def generate_msvs_projects(version): + """ Generate MSVS projects for the specified version. """ + sys.stdout.write('Generating '+version+' project files...') + os.environ['GYP_GENERATORS'] = 'msvs' + os.environ['GYP_MSVS_VERSION'] = version + gyper = [ 'python', 'tools/gyp_cef', os.path.relpath(os.path.join(output_dir, 'cefclient.gyp'), cef_dir) ] + RunAction(cef_dir, gyper); + move_file(os.path.relpath(os.path.join(output_dir, 'cefclient.sln')), \ + os.path.relpath(os.path.join(output_dir, 'cefclient'+version+'.sln'))) + +def create_msvs_projects(): + """ Create MSVS project files. """ + if not options.x64build: + generate_msvs_projects('2005'); + generate_msvs_projects('2008'); + generate_msvs_projects('2010'); + + # Fix the output directory path in all .vcproj and .vcxproj files. + files = [] + for file in get_files(os.path.join(output_dir, '*.vcproj')): + files.append(file) + for file in get_files(os.path.join(output_dir, '*.vcxproj')): + files.append(file) + for file in files: + data = read_file(file) + # fix the build directory path + data = data.replace('../../..\\build\\', 'out\\') + data = data.replace('..\\..\\..\\build\\', 'out\\') + # fix xcopy arguments + data = data.replace('xcopy \\', 'xcopy /') + if options.x64build: + # fix machine type + data = data.replace('MachineX86', 'MachineX64') + write_file(file, data) + +def create_xcode_projects(): + """ Create Xcode project files. """ + sys.stdout.write('Generating Xcode project files...') + os.environ['GYP_GENERATORS'] = 'xcode' + gyper = [ 'python', 'tools/gyp_cef', os.path.relpath(os.path.join(output_dir, 'cefclient.gyp'), cef_dir) ] + RunAction(cef_dir, gyper); + + # Post-process the Xcode project to fix file paths + src_file = os.path.join(output_dir, 'cefclient.xcodeproj/project.pbxproj') + data = read_file(src_file) + data = data.replace('../../../build/mac/', 'tools/') + data = data.replace('../../../build', 'build') + data = data.replace('../../../xcodebuild', 'xcodebuild') + write_file(src_file, data) + +def create_make_projects(): + """ Create make project files. """ + makefile = os.path.join(src_dir, 'Makefile') + makefile_tmp = '' + if path_exists(makefile): + # Back up the existing Makefile + makefile_tmp = makefile + '.cef_bak' + copy_file(makefile, makefile_tmp, options.quiet) + + # Generate make project files + sys.stdout.write('Generating make project files...') + os.environ['GYP_GENERATORS'] = 'make' + gyper = [ 'python', 'tools/gyp_cef', os.path.relpath(os.path.join(output_dir, 'cefclient.gyp'), cef_dir) ] + RunAction(cef_dir, gyper); + + # Copy the resulting Makefile to the destination directory + copy_file(makefile, output_dir, options.quiet) + + remove_file(makefile, options.quiet) + if makefile_tmp != '': + # Restore the original Makefile + move_file(makefile_tmp, makefile, options.quiet) + + # Fix the output directory path in Makefile and all .mk files. + find = os.path.relpath(output_dir, src_dir) + files = [os.path.join(output_dir, 'Makefile')] + for file in get_files(os.path.join(output_dir, '*.mk')): + files.append(file) + for file in files: + data = read_file(file) + data = data.replace(find, '.') + data = data.replace('/./', '/') + if os.path.basename(file) == 'Makefile': + # remove the quiet_cmd_regen_makefile section + pos = str.find(data, 'quiet_cmd_regen_makefile') + if pos >= 0: + epos = str.find(data, '#', pos) + if epos >= 0: + data = data[0:pos] + data[epos:] + write_file(file, data) + +def run(command_line, working_dir): + """ Run a command. """ + sys.stdout.write('-------- Running "'+command_line+'" in "'+\ + working_dir+'"...'+"\n") + args = shlex.split(command_line.replace('\\', '\\\\')) + return subprocess.check_call(args, cwd=working_dir, env=os.environ, + shell=(sys.platform == 'win32')) + +# cannot be loaded as a module +if __name__ != "__main__": + sys.stderr.write('This file cannot be loaded as a module!') + sys.exit() + +# parse command-line options +disc = """ +This utility builds the CEF Binary Distribution. +""" + +parser = OptionParser(description=disc) +parser.add_option('--output-dir', dest='outputdir', metavar='DIR', + help='output directory [required]') +parser.add_option('--allow-partial', + action='store_true', dest='allowpartial', default=False, + help='allow creation of partial distributions') +parser.add_option('--no-symbols', + action='store_true', dest='nosymbols', default=False, + help='don\'t create symbol files') +parser.add_option('--no-docs', + action='store_true', dest='nodocs', default=False, + help='don\'t create documentation') +parser.add_option('--no-archive', + action='store_true', dest='noarchive', default=False, + help='don\'t create archives for output directories') +parser.add_option('--ninja-build', + action='store_true', dest='ninjabuild', default=False, + help='build was created using ninja') +parser.add_option('--x64-build', + action='store_true', dest='x64build', default=False, + help='build was created for 64-bit systems') +parser.add_option('--minimal', + action='store_true', dest='minimal', default=False, + help='include only release build binary files') +parser.add_option('--client', + action='store_true', dest='client', default=False, + help='include only the cefclient application') +parser.add_option('-q', '--quiet', + action='store_true', dest='quiet', default=False, + help='do not output detailed status information') +(options, args) = parser.parse_args() + +# Test the operating system. +platform = ''; +if sys.platform == 'win32': + platform = 'windows' +elif sys.platform == 'darwin': + platform = 'macosx' +elif sys.platform.startswith('linux'): + platform = 'linux' + +# the outputdir option is required +if options.outputdir is None: + parser.print_help(sys.stderr) + sys.exit() + +if options.minimal and options.client: + print 'Invalid combination of options' + parser.print_help(sys.stderr) + sys.exit() + +if platform == 'windows' and options.x64build and not options.ninjabuild: + print 'x64 build on Windows requires ninja' + sys.exit() + +# script directory +script_dir = os.path.dirname(__file__) + +# CEF root directory +cef_dir = os.path.abspath(os.path.join(script_dir, os.pardir)) + +# src directory +src_dir = os.path.abspath(os.path.join(cef_dir, os.pardir)) + +# retrieve url, revision and date information +cef_info = get_svn_info(cef_dir) +cef_url = cef_info['url'] +cef_rev = cef_info['revision'] +chromium_info = get_svn_info(os.path.join(cef_dir, os.pardir)) +chromium_url = chromium_info['url'] +chromium_rev = chromium_info['revision'] +date = get_date() + +# Read and parse the version file (key=value pairs, one per line) +args = {} +read_version_file(os.path.join(cef_dir, 'VERSION'), args) +read_version_file(os.path.join(cef_dir, '../chrome/VERSION'), args) + +cef_ver = args['CEF_MAJOR']+'.'+args['BUILD']+'.'+cef_rev +chromium_ver = args['MAJOR']+'.'+args['MINOR']+'.'+args['BUILD']+'.'+args['PATCH'] + +# list of output directories to be archived +archive_dirs = [] + +platform_arch = '32' +if options.x64build: + platform_arch = '64' + +if platform == 'linux': + platform_arch = '' + lib_dir_name = 'lib.target' + if options.ninjabuild: + lib_dir_name = 'lib' + release_libcef_path = os.path.join(src_dir, 'out', 'Release', lib_dir_name, 'libcef.so'); + debug_libcef_path = os.path.join(src_dir, 'out', 'Debug', lib_dir_name, 'libcef.so'); + file_desc = '' + output = subprocess.check_output('file ' + release_libcef_path + ' ' + debug_libcef_path + '; exit 0', + env=os.environ, stderr=subprocess.STDOUT, shell=True) + if output.find('32-bit') != -1: + platform_arch = '32' + if output.find('64-bit') != -1: + platform_arch = '64' + +# output directory +output_dir_base = 'cef_binary_' + cef_ver +output_dir_name = output_dir_base + '_' + platform + platform_arch + +if options.minimal: + mode = 'minimal' + output_dir_name = output_dir_name + '_minimal' +elif options.client: + mode = 'client' + output_dir_name = output_dir_name + '_client' +else: + mode = 'standard' + +output_dir = create_output_dir(output_dir_name, options.outputdir) + +# create the README.TXT file +create_readme() + +# transfer the LICENSE.txt file +copy_file(os.path.join(cef_dir, 'LICENSE.txt'), output_dir, options.quiet) + +# read the variables list from the autogenerated cef_paths.gypi file +cef_paths = eval_file(os.path.join(cef_dir, 'cef_paths.gypi')) +cef_paths = cef_paths['variables'] + +# read the variables list from the manually edited cef_paths2.gypi file +cef_paths2 = eval_file(os.path.join(cef_dir, 'cef_paths2.gypi')) +cef_paths2 = cef_paths2['variables'] + +if mode == 'standard': + # create the include directory + include_dir = os.path.join(output_dir, 'include') + make_dir(include_dir, options.quiet) + + # create the cefclient directory + cefclient_dir = os.path.join(output_dir, 'cefclient') + make_dir(cefclient_dir, options.quiet) + + # create the libcef_dll_wrapper directory + wrapper_dir = os.path.join(output_dir, 'libcef_dll') + make_dir(wrapper_dir, options.quiet) + + # transfer common include files + transfer_gypi_files(cef_dir, cef_paths2['includes_common'], \ + 'include/', include_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths2['includes_capi'], \ + 'include/', include_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths2['includes_wrapper'], \ + 'include/', include_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths['autogen_cpp_includes'], \ + 'include/', include_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths['autogen_capi_includes'], \ + 'include/', include_dir, options.quiet) + + # transfer common cefclient files + transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_common'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths2['cefclient_bundle_resources_common'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + + # transfer common libcef_dll_wrapper files + transfer_gypi_files(cef_dir, cef_paths2['libcef_dll_wrapper_sources_common'], \ + 'libcef_dll/', wrapper_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths['autogen_client_side'], \ + 'libcef_dll/', wrapper_dir, options.quiet) + + # transfer gyp files + copy_file(os.path.join(script_dir, 'distrib/cefclient.gyp'), output_dir, options.quiet) + paths_gypi = os.path.join(cef_dir, 'cef_paths2.gypi') + data = read_file(paths_gypi) + data = data.replace('tests/cefclient/', 'cefclient/') + write_file(os.path.join(output_dir, 'cef_paths2.gypi'), data) + copy_file(os.path.join(cef_dir, 'cef_paths.gypi'), \ + os.path.join(output_dir, 'cef_paths.gypi'), options.quiet) + + # transfer additional files + transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/transfer.cfg'), \ + output_dir, options.quiet) + +if platform == 'windows': + if options.ninjabuild: + out_dir = os.path.join(src_dir, 'out') + libcef_dll_file = 'libcef.dll.lib' + else: + out_dir = os.path.join(src_dir, 'build') + libcef_dll_file = 'lib/libcef.lib' + + valid_build_dir = None + + build_dir_suffix = '' + if options.x64build: + build_dir_suffix = '_x64' + + if mode == 'standard': + # transfer Debug files + build_dir = os.path.join(out_dir, 'Debug' + build_dir_suffix); + if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.exe')): + valid_build_dir = build_dir + dst_dir = os.path.join(output_dir, 'Debug') + make_dir(dst_dir, options.quiet) + copy_files(os.path.join(script_dir, 'distrib/win/*.dll'), dst_dir, options.quiet) + copy_files(os.path.join(build_dir, '*.dll'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, libcef_dll_file), os.path.join(dst_dir, 'libcef.lib'), \ + options.quiet) + + if not options.nosymbols: + # create the symbol output directory + symbol_output_dir = create_output_dir(output_dir_name + '_debug_symbols', options.outputdir) + # transfer contents + copy_file(os.path.join(build_dir, 'libcef.dll.pdb'), symbol_output_dir, options.quiet) + else: + sys.stderr.write("No Debug build files.\n") + + # transfer Release files + build_dir = os.path.join(out_dir, 'Release' + build_dir_suffix); + if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.exe')): + valid_build_dir = build_dir + dst_dir = os.path.join(output_dir, 'Release') + make_dir(dst_dir, options.quiet) + copy_files(os.path.join(script_dir, 'distrib/win/*.dll'), dst_dir, options.quiet) + copy_files(os.path.join(build_dir, '*.dll'), dst_dir, options.quiet) + + if mode != 'client': + copy_file(os.path.join(build_dir, libcef_dll_file), os.path.join(dst_dir, 'libcef.lib'), \ + options.quiet) + else: + copy_file(os.path.join(build_dir, 'cefclient.exe'), dst_dir, options.quiet) + + if not options.nosymbols: + # create the symbol output directory + symbol_output_dir = create_output_dir(output_dir_name + '_release_symbols', options.outputdir) + # transfer contents + copy_file(os.path.join(build_dir, 'libcef.dll.pdb'), symbol_output_dir, options.quiet) + else: + sys.stderr.write("No Release build files.\n") + + if not valid_build_dir is None: + # transfer resource files + build_dir = valid_build_dir + if mode == 'client': + dst_dir = os.path.join(output_dir, 'Release') + else: + dst_dir = os.path.join(output_dir, 'Resources') + make_dir(dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'cef.pak'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'devtools_resources.pak'), dst_dir, options.quiet) + copy_dir(os.path.join(build_dir, 'locales'), os.path.join(dst_dir, 'locales'), options.quiet) + + if mode == 'standard': + # transfer include files + transfer_gypi_files(cef_dir, cef_paths2['includes_win'], \ + 'include/', include_dir, options.quiet) + + # transfer cefclient files + transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_win'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + + # transfer additional files, if any + transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/win/transfer.cfg'), \ + output_dir, options.quiet) + + create_msvs_projects() + + if not options.nodocs: + # generate doc files + os.popen('make_cppdocs.bat '+cef_rev) + + src_dir = os.path.join(cef_dir, 'docs') + if path_exists(src_dir): + # create the docs output directory + docs_output_dir = create_output_dir(output_dir_base + '_docs', options.outputdir) + # transfer contents + copy_dir(src_dir, docs_output_dir, options.quiet) + +elif platform == 'macosx': + if options.ninjabuild: + out_dir = os.path.join(src_dir, 'out') + else: + out_dir = os.path.join(src_dir, 'xcodebuild') + + valid_build_dir = None + + if mode == 'standard': + # transfer Debug files + build_dir = os.path.join(out_dir, 'Debug') + if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.app')): + valid_build_dir = build_dir + dst_dir = os.path.join(output_dir, 'Debug') + make_dir(dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'ffmpegsumo.so'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'libcef.dylib'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'libplugin_carbon_interpose.dylib'), dst_dir, options.quiet) + + # transfer Release files + build_dir = os.path.join(out_dir, 'Release') + if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient.app')): + valid_build_dir = build_dir + dst_dir = os.path.join(output_dir, 'Release') + make_dir(dst_dir, options.quiet) + if mode != 'client': + copy_file(os.path.join(build_dir, 'ffmpegsumo.so'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'libcef.dylib'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'libplugin_carbon_interpose.dylib'), dst_dir, options.quiet) + else: + copy_dir(os.path.join(build_dir, 'cefclient.app'), os.path.join(dst_dir, 'cefclient.app'), options.quiet) + + if not options.nosymbols: + # create the symbol output directory + symbol_output_dir = create_output_dir(output_dir_name + '_release_symbols', options.outputdir) + + # create the real dSYM file from the "fake" dSYM file + sys.stdout.write("Creating the real dSYM file...\n") + src_path = os.path.join(build_dir, 'libcef.dylib.dSYM/Contents/Resources/DWARF/libcef.dylib') + dst_path = os.path.join(symbol_output_dir, 'libcef.dylib.dSYM') + run('dsymutil '+src_path+' -o '+dst_path, cef_dir) + + if not valid_build_dir is None and mode != 'client': + # transfer resource files + build_dir = valid_build_dir + dst_dir = os.path.join(output_dir, 'Resources') + make_dir(dst_dir, options.quiet) + copy_files(os.path.join(build_dir, 'cefclient.app/Contents/Frameworks/Chromium Embedded Framework.framework/Resources/*.*'), \ + dst_dir, options.quiet) + + if mode == 'standard': + # transfer include files + transfer_gypi_files(cef_dir, cef_paths2['includes_mac'], \ + 'include/', include_dir, options.quiet) + + # transfer cefclient files + transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_mac'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_mac_helper'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths2['cefclient_bundle_resources_mac'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + + # transfer cefclient/mac files + copy_dir(os.path.join(cef_dir, 'tests/cefclient/mac/'), os.path.join(output_dir, 'cefclient/mac/'), \ + options.quiet) + + # transfer additional files, if any + transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/mac/transfer.cfg'), \ + output_dir, options.quiet) + + create_xcode_projects() + +elif platform == 'linux': + out_dir = os.path.join(src_dir, 'out') + if options.ninjabuild: + lib_dir_name = 'lib' + else: + lib_dir_name = 'lib.target' + + valid_build_dir = None + + if mode == 'standard': + # transfer Debug files + build_dir = os.path.join(out_dir, 'Debug'); + if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient')): + valid_build_dir = build_dir + dst_dir = os.path.join(output_dir, 'Debug') + make_dir(dst_dir, options.quiet) + copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'libffmpegsumo.so'), dst_dir, options.quiet) + else: + sys.stderr.write("No Debug build files.\n") + + # transfer Release files + build_dir = os.path.join(out_dir, 'Release'); + if not options.allowpartial or path_exists(os.path.join(build_dir, 'cefclient')): + valid_build_dir = build_dir + dst_dir = os.path.join(output_dir, 'Release') + make_dir(dst_dir, options.quiet) + + if mode == 'client': + lib_dst_dir = os.path.join(dst_dir, lib_dir_name) + make_dir(lib_dst_dir, options.quiet) + copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), lib_dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'cefclient'), dst_dir, options.quiet) + else: + copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'libffmpegsumo.so'), dst_dir, options.quiet) + else: + sys.stderr.write("No Release build files.\n") + + if not valid_build_dir is None: + # transfer resource files + build_dir = valid_build_dir + if mode == 'client': + dst_dir = os.path.join(output_dir, 'Release') + copy_dir(os.path.join(build_dir, 'files'), os.path.join(dst_dir, 'files'), options.quiet) + else: + dst_dir = os.path.join(output_dir, 'Resources') + make_dir(dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'cef.pak'), dst_dir, options.quiet) + copy_file(os.path.join(build_dir, 'devtools_resources.pak'), dst_dir, options.quiet) + copy_dir(os.path.join(build_dir, 'locales'), os.path.join(dst_dir, 'locales'), options.quiet) + + if mode == 'standard': + # transfer include files + transfer_gypi_files(cef_dir, cef_paths2['includes_linux'], \ + 'include/', include_dir, options.quiet) + + # transfer cefclient files + transfer_gypi_files(cef_dir, cef_paths2['cefclient_sources_linux'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + transfer_gypi_files(cef_dir, cef_paths2['cefclient_bundle_resources_linux'], \ + 'tests/cefclient/', cefclient_dir, options.quiet) + + # transfer additional files, if any + copy_file(os.path.join(script_dir, 'distrib/linux/build.sh'), output_dir, options.quiet) + transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib/linux/transfer.cfg'), \ + output_dir, options.quiet) + + create_make_projects() + +if not options.noarchive: + # create an archive for each output directory + archive_extenstion = '.zip' + if os.getenv('CEF_COMMAND_7ZIP', '') != '': + archive_extenstion = '.7z' + for dir in archive_dirs: + zip_file = os.path.split(dir)[1] + archive_extenstion + if not options.quiet: + sys.stdout.write('Creating '+zip_file+"...\n") + if archive_extenstion == '.zip': + create_archive(dir, os.path.join(dir, os.pardir, zip_file)) + else: + create_7z_archive(dir, os.path.join(dir, os.pardir, zip_file)) diff --git a/tools/svn_util.py b/tools/svn_util.py index 9841112ef..72e2f6df5 100644 --- a/tools/svn_util.py +++ b/tools/svn_util.py @@ -1,70 +1,70 @@ -# Copyright (c) 2012 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. - -import os -import sys -import subprocess -import urllib -import xml.etree.ElementTree as ET - -def check_url(url): - """ Check the URL and raise an exception if invalid. """ - if ':' in url[:7]: - parts = url.split(':', 1) - if (parts[0] == 'http' or parts[0] == 'https' or parts[0] == 'svn') and \ - parts[1] == urllib.quote(parts[1]): - return url - sys.stderr.write('Invalid URL: '+url+"\n") - raise Exception('Invalid URL: '+url) - -def get_svn_info(path): - """ Retrieves the URL and revision from svn info. """ - url = 'None' - rev = 'None' - if path[0:4] == 'http' or os.path.exists(path): - try: - if sys.platform == 'win32': - # Force use of the SVN version bundled with depot_tools. - svn = 'svn.bat' - else: - svn = 'svn' - p = subprocess.Popen([svn, 'info', '--xml', path], \ - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, err = p.communicate() - if err == '': - tree = ET.ElementTree(ET.fromstring(out)) - entry = tree.getroot().find('entry') - url = entry.find('url').text - rev = entry.attrib['revision'] - else: - raise Exception("Failed to execute svn info:\n"+err+"\n") - except IOError, (errno, strerror): - sys.stderr.write('Failed to read svn info: '+strerror+"\n") - raise - except: - raise - return {'url': url, 'revision': rev} - -def get_revision(path = '.'): - """ Retrieves the revision from svn info. """ - info = get_svn_info(path) - if info['revision'] == 'None': - raise Exception('Unable to retrieve SVN revision for "'+path+'"') - return info['revision'] - -def get_changed_files(path = '.'): - """ Retrieves the list of changed files from svn status. """ - files = [] - if os.path.exists(path): - try: - stream = os.popen('svn status '+path) - for line in stream: - status = line[0] - # Return paths with add, modify and switch status. - if status == 'A' or status == 'M' or status == 'S': - files.append(line[8:].strip()) - except IOError, (errno, strerror): - sys.stderr.write('Failed to read svn status: '+strerror+"\n") - raise - return files +# Copyright (c) 2012 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. + +import os +import sys +import subprocess +import urllib +import xml.etree.ElementTree as ET + +def check_url(url): + """ Check the URL and raise an exception if invalid. """ + if ':' in url[:7]: + parts = url.split(':', 1) + if (parts[0] == 'http' or parts[0] == 'https' or parts[0] == 'svn') and \ + parts[1] == urllib.quote(parts[1]): + return url + sys.stderr.write('Invalid URL: '+url+"\n") + raise Exception('Invalid URL: '+url) + +def get_svn_info(path): + """ Retrieves the URL and revision from svn info. """ + url = 'None' + rev = 'None' + if path[0:4] == 'http' or os.path.exists(path): + try: + if sys.platform == 'win32': + # Force use of the SVN version bundled with depot_tools. + svn = 'svn.bat' + else: + svn = 'svn' + p = subprocess.Popen([svn, 'info', '--xml', path], \ + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate() + if err == '': + tree = ET.ElementTree(ET.fromstring(out)) + entry = tree.getroot().find('entry') + url = entry.find('url').text + rev = entry.attrib['revision'] + else: + raise Exception("Failed to execute svn info:\n"+err+"\n") + except IOError, (errno, strerror): + sys.stderr.write('Failed to read svn info: '+strerror+"\n") + raise + except: + raise + return {'url': url, 'revision': rev} + +def get_revision(path = '.'): + """ Retrieves the revision from svn info. """ + info = get_svn_info(path) + if info['revision'] == 'None': + raise Exception('Unable to retrieve SVN revision for "'+path+'"') + return info['revision'] + +def get_changed_files(path = '.'): + """ Retrieves the list of changed files from svn status. """ + files = [] + if os.path.exists(path): + try: + stream = os.popen('svn status '+path) + for line in stream: + status = line[0] + # Return paths with add, modify and switch status. + if status == 'A' or status == 'M' or status == 'S': + files.append(line[8:].strip()) + except IOError, (errno, strerror): + sys.stderr.write('Failed to read svn status: '+strerror+"\n") + raise + return files