summaryrefslogtreecommitdiff
path: root/win8
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2014-03-31 11:51:25 +0100
committerBen Murdoch <benm@google.com>2014-03-31 11:51:25 +0100
commiteffb81e5f8246d0db0270817048dc992db66e9fb (patch)
treecc45ced7dfde038c8f3d022ee1eeac207a68761e /win8
parent4d26337013537c1acafbcb63b9b2b7e404c3adc9 (diff)
downloadchromium_org-effb81e5f8246d0db0270817048dc992db66e9fb.tar.gz
Merge from Chromium at DEPS revision 260458
This commit was generated by merge_to_master.py. Change-Id: I140fa91b7f09c8efba4424e99ccb87b94a11d022
Diffstat (limited to 'win8')
-rw-r--r--win8/delegate_execute/command_execute_impl.cc2
-rw-r--r--win8/metro_driver/chrome_app_view_ash.cc42
-rw-r--r--win8/metro_driver/direct3d_helper.cc47
-rw-r--r--win8/metro_driver/metro_driver.cc66
-rw-r--r--win8/metro_driver/metro_driver.gyp7
-rw-r--r--win8/metro_driver/metro_driver_win7.cc751
-rw-r--r--win8/viewer/metro_viewer_process_host.cc40
-rw-r--r--win8/viewer/metro_viewer_process_host.h1
8 files changed, 794 insertions, 162 deletions
diff --git a/win8/delegate_execute/command_execute_impl.cc b/win8/delegate_execute/command_execute_impl.cc
index 405b24f0fc..4c37e7b952 100644
--- a/win8/delegate_execute/command_execute_impl.cc
+++ b/win8/delegate_execute/command_execute_impl.cc
@@ -432,7 +432,7 @@ EC_HOST_UI_MODE CommandExecuteImpl::GetLaunchMode() {
base::FilePath chrome_exe;
if (!FindChromeExe(&chrome_exe) ||
ShellUtil::GetChromeDefaultStateFromPath(chrome_exe) !=
- ShellUtil::DefaultState::IS_DEFAULT) {
+ ShellUtil::IS_DEFAULT) {
AtlTrace("Chrome is not default: launching in desktop mode\n");
launch_mode = ECHUIM_DESKTOP;
launch_mode_determined = true;
diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc
index dc5923c737..8e1f0e64d2 100644
--- a/win8/metro_driver/chrome_app_view_ash.cc
+++ b/win8/metro_driver/chrome_app_view_ash.cc
@@ -17,6 +17,7 @@
#include "base/threading/thread.h"
#include "base/win/metro.h"
#include "base/win/win_util.h"
+#include "base/win/windows_version.h"
#include "chrome/common/chrome_switches.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
@@ -272,8 +273,8 @@ bool WaitForChromeIPCConnection(const std::string& channel_name) {
int ms_elapsed = 0;
while (!IPC::Channel::IsNamedServerInitialized(channel_name) &&
ms_elapsed < 10000) {
- ms_elapsed += 500;
- Sleep(500);
+ ms_elapsed += 100;
+ Sleep(100);
}
return IPC::Channel::IsNamedServerInitialized(channel_name);
}
@@ -573,7 +574,7 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) {
CheckHR(hr);
mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher;
- hr = window_->get_Dispatcher(&dispatcher);
+ hr = window_->get_Dispatcher(dispatcher.GetAddressOf());
CheckHR(hr, "Get Dispatcher failed.");
mswr::ComPtr<winui::Core::ICoreAcceleratorKeys> accelerator_keys;
@@ -602,21 +603,23 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) {
&window_activated_token_);
CheckHR(hr);
- // Register for edge gesture notifications.
- mswr::ComPtr<winui::Input::IEdgeGestureStatics> edge_gesture_statics;
- hr = winrt_utils::CreateActivationFactory(
- RuntimeClass_Windows_UI_Input_EdgeGesture,
- edge_gesture_statics.GetAddressOf());
- CheckHR(hr);
-
- mswr::ComPtr<winui::Input::IEdgeGesture> edge_gesture;
- hr = edge_gesture_statics->GetForCurrentView(&edge_gesture);
- CheckHR(hr);
-
- hr = edge_gesture->add_Completed(mswr::Callback<EdgeEventHandler>(
- this, &ChromeAppViewAsh::OnEdgeGestureCompleted).Get(),
- &edgeevent_token_);
- CheckHR(hr);
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
+ // Register for edge gesture notifications only for Windows 8 and above.
+ mswr::ComPtr<winui::Input::IEdgeGestureStatics> edge_gesture_statics;
+ hr = winrt_utils::CreateActivationFactory(
+ RuntimeClass_Windows_UI_Input_EdgeGesture,
+ edge_gesture_statics.GetAddressOf());
+ CheckHR(hr);
+
+ mswr::ComPtr<winui::Input::IEdgeGesture> edge_gesture;
+ hr = edge_gesture_statics->GetForCurrentView(&edge_gesture);
+ CheckHR(hr);
+
+ hr = edge_gesture->add_Completed(mswr::Callback<EdgeEventHandler>(
+ this, &ChromeAppViewAsh::OnEdgeGestureCompleted).Get(),
+ &edgeevent_token_);
+ CheckHR(hr);
+ }
// By initializing the direct 3D swap chain with the corewindow
// we can now directly blit to it from the browser process.
@@ -627,6 +630,7 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) {
IFACEMETHODIMP
ChromeAppViewAsh::Load(HSTRING entryPoint) {
+ // On Win7 |entryPoint| is NULL.
DVLOG(1) << __FUNCTION__;
return S_OK;
}
@@ -635,7 +639,7 @@ IFACEMETHODIMP
ChromeAppViewAsh::Run() {
DVLOG(1) << __FUNCTION__;
mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher;
- HRESULT hr = window_->get_Dispatcher(&dispatcher);
+ HRESULT hr = window_->get_Dispatcher(dispatcher.GetAddressOf());
CheckHR(hr, "Dispatcher failed.");
hr = window_->Activate();
diff --git a/win8/metro_driver/direct3d_helper.cc b/win8/metro_driver/direct3d_helper.cc
index 056e84b4cb..d0c30cf712 100644
--- a/win8/metro_driver/direct3d_helper.cc
+++ b/win8/metro_driver/direct3d_helper.cc
@@ -7,7 +7,10 @@
#include "win8/metro_driver/winrt_utils.h"
#include "base/logging.h"
+#include "base/win/windows_version.h"
+#include <corewindow.h>
+#include <windows.applicationmodel.core.h>
#include <windows.graphics.display.h>
namespace {
@@ -83,9 +86,15 @@ void Direct3DHelper::CreateDeviceResources() {
}
void Direct3DHelper::CreateWindowSizeDependentResources() {
- CheckIfFailed(window_->get_Bounds(&window_bounds_));
- float window_width = ConvertDipsToPixels(window_bounds_.Width);
- float window_height = ConvertDipsToPixels(window_bounds_.Height);
+ float window_width = 0;
+ float window_height = 0;
+
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
+ // Windows 8 returns in DIPs.
+ CheckIfFailed(window_->get_Bounds(&window_bounds_));
+ window_width = ConvertDipsToPixels(window_width);
+ window_height = ConvertDipsToPixels(window_height);
+ }
// TODO(scottmg): Orientation.
@@ -116,12 +125,32 @@ void Direct3DHelper::CreateWindowSizeDependentResources() {
CheckIfFailed(dxgi_adapter->GetParent(
__uuidof(IDXGIFactory2), &dxgi_factory));
- CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow(
- d3d_device_.Get(),
- reinterpret_cast<IUnknown*>(window_),
- &swap_chain_desc,
- nullptr,
- &swap_chain_));
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
+ // On Win8 we need the CoreWindow interface to create the Swapchain.
+ CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow(
+ d3d_device_.Get(),
+ reinterpret_cast<IUnknown*>(window_),
+ &swap_chain_desc,
+ nullptr,
+ &swap_chain_));
+ } else {
+ // On Win7 we need the raw HWND to create the Swapchain.
+ mswr::ComPtr<ICoreWindowInterop> interop;
+ CheckIfFailed(window_->QueryInterface(interop.GetAddressOf()));
+ HWND window = NULL;
+ interop->get_WindowHandle(&window);
+
+ swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
+ swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+ CheckIfFailed(dxgi_factory->CreateSwapChainForHwnd(
+ d3d_device_.Get(),
+ window,
+ &swap_chain_desc,
+ nullptr,
+ nullptr,
+ &swap_chain_));
+ }
}
}
diff --git a/win8/metro_driver/metro_driver.cc b/win8/metro_driver/metro_driver.cc
index eb87754c71..a60af6b240 100644
--- a/win8/metro_driver/metro_driver.cc
+++ b/win8/metro_driver/metro_driver.cc
@@ -13,11 +13,9 @@
#include "base/logging.h"
#include "base/logging_win.h"
#include "base/win/scoped_comptr.h"
+#include "base/win/windows_version.h"
#include "win8/metro_driver/winrt_utils.h"
-// TODO(siggi): Move this to GYP.
-#pragma comment(lib, "runtimeobject.lib")
-
namespace {
LONG WINAPI ErrorReportingHandler(EXCEPTION_POINTERS* ex_info) {
@@ -37,6 +35,17 @@ LONG WINAPI ErrorReportingHandler(EXCEPTION_POINTERS* ex_info) {
return EXCEPTION_CONTINUE_SEARCH;
}
+void SetMetroReportingFlags() {
+#if !defined(NDEBUG)
+ // Set the error reporting flags to always raise an exception,
+ // which is then processed by our vectored exception handling
+ // above to log the error message.
+ winfoundtn::Diagnostics::SetErrorReportingFlags(
+ winfoundtn::Diagnostics::UseSetErrorInfo |
+ winfoundtn::Diagnostics::ForceExceptions);
+#endif
+}
+
// TODO(robertshield): This GUID is hard-coded in a bunch of places that
// don't allow explicit includes. Find a single place for it to live.
// {7FE69228-633E-4f06-80C1-527FEA23E3A7}
@@ -44,7 +53,7 @@ const GUID kChromeTraceProviderName = {
0x7fe69228, 0x633e, 0x4f06,
{ 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } };
-}
+} // namespace
#if !defined(COMPONENT_BUILD)
// Required for base initialization.
@@ -54,53 +63,58 @@ const GUID kChromeTraceProviderName = {
base::AtExitManager at_exit;
#endif
+mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows8() {
+ SetMetroReportingFlags();
+ HRESULT hr = ::Windows::Foundation::Initialize(RO_INIT_MULTITHREADED);
+ if (FAILED(hr))
+ CHECK(false);
+ mswr::ComPtr<winapp::Core::ICoreApplication> core_app;
+ hr = winrt_utils::CreateActivationFactory(
+ RuntimeClass_Windows_ApplicationModel_Core_CoreApplication,
+ core_app.GetAddressOf());
+ if (FAILED(hr))
+ CHECK(false);
+ return core_app;
+}
+
+mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows7();
+
extern "C" __declspec(dllexport)
int InitMetro() {
+ // Metro mode or its emulation is not supported in Vista or XP.
+ if (base::win::GetVersion() < base::win::VERSION_WIN7)
+ return 1;
// Initialize the command line.
CommandLine::Init(0, NULL);
+ // Initialize the logging system.
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
logging::InitLogging(settings);
-
#if defined(NDEBUG)
logging::SetMinLogLevel(logging::LOG_ERROR);
#else
logging::SetMinLogLevel(logging::LOG_VERBOSE);
- // Set the error reporting flags to always raise an exception,
- // which is then processed by our vectored exception handling
- // above to log the error message.
- winfoundtn::Diagnostics::SetErrorReportingFlags(
- winfoundtn::Diagnostics::UseSetErrorInfo |
- winfoundtn::Diagnostics::ForceExceptions);
-
- HANDLE registration =
+ HANDLE registration =
::AddVectoredExceptionHandler(TRUE, ErrorReportingHandler);
#endif
-
// Enable trace control and transport through event tracing for Windows.
logging::LogEventProvider::Initialize(kChromeTraceProviderName);
-
DVLOG(1) << "InitMetro";
- mswrw::RoInitializeWrapper ro_initializer(RO_INIT_MULTITHREADED);
- CheckHR(ro_initializer, "RoInitialize failed");
-
+ // OS specific initialization.
mswr::ComPtr<winapp::Core::ICoreApplication> core_app;
- HRESULT hr = winrt_utils::CreateActivationFactory(
- RuntimeClass_Windows_ApplicationModel_Core_CoreApplication,
- core_app.GetAddressOf());
- CheckHR(hr, "Failed to create app factory");
- if (FAILED(hr))
- return 1;
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ core_app = InitWindows7();
+ else
+ core_app = InitWindows8();
auto view_factory = mswr::Make<ChromeAppViewFactory>(core_app.Get());
- hr = core_app->Run(view_factory.Get());
+ HRESULT hr = core_app->Run(view_factory.Get());
DVLOG(1) << "exiting InitMetro, hr=" << hr;
#if !defined(NDEBUG)
::RemoveVectoredExceptionHandler(registration);
#endif
-
return hr;
}
diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp
index 42fd9c72d5..34fbcdd988 100644
--- a/win8/metro_driver/metro_driver.gyp
+++ b/win8/metro_driver/metro_driver.gyp
@@ -22,6 +22,12 @@
'AdditionalDependencies': [
'D2D1.lib',
'D3D11.lib',
+ 'runtimeobject.lib',
+ ],
+ 'DelayLoadDLLs': [
+ 'API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL',
+ 'API-MS-WIN-CORE-WINRT-L1-1-0.DLL',
+ 'API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL',
],
},
'VCCLCompilerTool': {
@@ -76,6 +82,7 @@
'display_properties.h',
'metro_driver.cc',
'metro_driver.h',
+ 'metro_driver_win7.cc',
'stdafx.h',
'winrt_utils.cc',
'winrt_utils.h',
diff --git a/win8/metro_driver/metro_driver_win7.cc b/win8/metro_driver/metro_driver_win7.cc
index 253e527b8c..2e5aba73fc 100644
--- a/win8/metro_driver/metro_driver_win7.cc
+++ b/win8/metro_driver/metro_driver_win7.cc
@@ -3,41 +3,11 @@
// found in the LICENSE file.
#include "stdafx.h"
+#include <corewindow.h>
-EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+#include "base/logging.h"
-struct Globals {
- LPTHREAD_START_ROUTINE host_main;
- void* host_context;
- HWND core_window;
- HWND host_window;
- HANDLE host_thread;
- DWORD main_thread_id;
-} globals;
-
-
-void ODS(const char* str, LONG_PTR val = 0) {
- char buf[80];
- size_t len = strlen(str);
- if (len > 50) {
- ::OutputDebugStringA("ODS: buffer too long");
- return;
- }
-
- if (str[0] == '!') {
- // Fatal error.
- DWORD gle = ::GetLastError();
- if (::IsDebuggerPresent())
- __debugbreak();
- wsprintfA(buf, "ODS:fatal %s (%p) gle=0x%x", str, val, gle);
- ::MessageBoxA(NULL, buf, "!!!", MB_OK);
- ::ExitProcess(gle);
- } else {
- // Just information.
- wsprintfA(buf, "ODS:%s (%p)\n", str, val);
- ::OutputDebugStringA(buf);
- }
-}
+EXTERN_C IMAGE_DOS_HEADER __ImageBase;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam) {
@@ -45,15 +15,18 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
HDC hdc;
switch (message) {
case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
+ hdc = ::BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
break;
+ case WM_LBUTTONUP:
+ // TODO(cpu): Remove this test code.
+ ::InvalidateRect(hwnd, NULL, TRUE);
+ break;
case WM_DESTROY:
PostQuitMessage(0);
- ODS("Metro WM_DESTROY received");
break;
default:
- return DefWindowProc(hwnd, message, wparam, lparam);
+ return ::DefWindowProc(hwnd, message, wparam, lparam);
}
return 0;
}
@@ -62,78 +35,660 @@ HWND CreateMetroTopLevelWindow() {
HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase);
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(wcex);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInst;
- wcex.hIcon = 0;
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1);
- wcex.lpszMenuName = 0;
- wcex.lpszClassName = L"Windows.UI.Core.CoreWindow";
- wcex.hIconSm = 0;
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInst;
+ wcex.hIcon = 0;
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1);
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = L"Windows.UI.Core.CoreWindow";
+ wcex.hIconSm = 0;
HWND hwnd = ::CreateWindowExW(0,
MAKEINTATOM(::RegisterClassExW(&wcex)),
- L"metro_metro",
- WS_POPUP,
- 0, 0, 0, 0,
+ L"metro_win7",
+ WS_POPUP | WS_VISIBLE,
+ 0, 0, 1024, 1024,
NULL, NULL, hInst, NULL);
return hwnd;
}
-DWORD WINAPI HostThread(void*) {
- // The sleeps simulates the delay we have in the actual metro code
- // which takes in account the corewindow being created and some other
- // unknown machinations of metro.
- ODS("Chrome main thread", ::GetCurrentThreadId());
- ::Sleep(30);
- return globals.host_main(globals.host_context);
-}
+typedef winfoundtn::ITypedEventHandler<
+ winapp::Core::CoreApplicationView*,
+ winapp::Activation::IActivatedEventArgs*> ActivatedHandler;
-extern "C" __declspec(dllexport)
-int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) {
- ODS("InitMetro [Win7 emulation]");
- HWND window = CreateMetroTopLevelWindow();
- if (!window)
- return 1;
- // This magic incatation tells windows that the window is going fullscreen
- // so the taskbar gets out of the wait automatically.
- ::SetWindowPos(window,
- HWND_TOP,
- 0,0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- SWP_SHOWWINDOW);
-
- // Ready to start our caller.
- globals.core_window = window;
- globals.host_main = thread_proc;
- globals.host_context = context;
- HANDLE thread = ::CreateThread(NULL, 0, &HostThread, NULL, 0, NULL);
-
- // Main message loop.
- MSG msg = {0};
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return (int) msg.wParam;
-}
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler;
-extern "C" _declspec(dllexport) HWND GetRootWindow() {
- ODS("GetRootWindow", ULONG_PTR(globals.core_window));
- return globals.core_window;
-}
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::AutomationProviderRequestedEventArgs*>
+ AutomationProviderHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::CharacterReceivedEventArgs*> CharEventHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::CoreWindowEventArgs*> CoreWindowEventHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::InputEnabledEventArgs*> InputEnabledEventHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::KeyEventArgs*> KeyEventHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::PointerEventArgs*> PointerEventHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::TouchHitTestingEventArgs*> TouchHitTestHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreWindow*,
+ winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler;
+
+typedef winfoundtn::ITypedEventHandler<
+ winui::Core::CoreDispatcher*,
+ winui::Core::AcceleratorKeyEventArgs*> AcceleratorKeyEventHandler;
+
+// The following classes are the emulation of the WinRT system as exposed
+// to metro applications. There is one application (ICoreApplication) which
+// contains a series of Views (ICoreApplicationView) each one of them
+// containing a CoreWindow which represents a surface that can drawn to
+// and that receives events.
+//
+// Here is the general dependency hierachy in terms of interfaces:
+//
+// IFrameworkViewSource --> IFrameworkView
+// ^ |
+// | | metro app
+// ---------------------------------------------------------------------
+// | | winRT system
+// | v
+// ICoreApplication ICoreApplicationView
+// |
+// v
+// ICoreWindow -----> ICoreWindowInterop
+// | |
+// | |
+// v V
+// ICoreDispatcher <==> real HWND
+//
+class CoreDispacherEmulation :
+ public mswr::RuntimeClass<
+ winui::Core::ICoreDispatcher,
+ winui::Core::ICoreAcceleratorKeys> {
+ public:
+ // ICoreDispatcher implementation:
+ virtual HRESULT STDMETHODCALLTYPE get_HasThreadAccess(boolean* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE ProcessEvents(
+ winui::Core::CoreProcessEventsOption options) {
+ // We don't support the other message pump modes. So we basically enter a
+ // traditional message loop that we only exit a teardown.
+ if (options != winui::Core::CoreProcessEventsOption_ProcessUntilQuit)
+ return E_FAIL;
+
+ MSG msg = {0};
+ while(::GetMessage(&msg, NULL, 0, 0) != 0) {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ // TODO(cpu): figure what to do with msg.WParam which we would normally
+ // return here.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE RunAsync(
+ winui::Core::CoreDispatcherPriority priority,
+ winui::Core::IDispatchedHandler *agileCallback,
+ ABI::Windows::Foundation::IAsyncAction** asyncAction) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE RunIdleAsync(
+ winui::Core::IIdleDispatchedHandler *agileCallback,
+ winfoundtn::IAsyncAction** asyncAction) {
+ return S_OK;
+ }
+
+ // ICoreAcceleratorKeys implementation:
+ virtual HRESULT STDMETHODCALLTYPE add_AcceleratorKeyActivated(
+ AcceleratorKeyEventHandler* handler,
+ EventRegistrationToken *pCookie) {
+ // TODO(cpu): implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_AcceleratorKeyActivated(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+};
+
+class CoreWindowEmulation
+ : public mswr::RuntimeClass<
+ mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>,
+ winui::Core::ICoreWindow, ICoreWindowInterop> {
+ public:
+ CoreWindowEmulation() : core_hwnd_(NULL) {
+ dispatcher_ = mswr::Make<CoreDispacherEmulation>();
+ core_hwnd_ = CreateMetroTopLevelWindow();
+ }
+
+ ~CoreWindowEmulation() {
+ ::DestroyWindow(core_hwnd_);
+ }
+
+ // ICoreWindow implementation:
+ virtual HRESULT STDMETHODCALLTYPE get_AutomationHostProvider(
+ IInspectable** value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_Bounds(
+ winfoundtn::Rect* value) {
+ RECT rect;
+ if (!::GetClientRect(core_hwnd_, &rect))
+ return E_FAIL;
+ value->Width = rect.right;
+ value->Height = rect.bottom;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_CustomProperties(
+ winfoundtn::Collections::IPropertySet** value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_Dispatcher(
+ winui::Core::ICoreDispatcher** value) {
+ return dispatcher_.CopyTo(value);
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_FlowDirection(
+ winui::Core::CoreWindowFlowDirection* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE put_FlowDirection(
+ winui::Core::CoreWindowFlowDirection value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_IsInputEnabled(
+ boolean* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE put_IsInputEnabled(
+ boolean value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_PointerCursor(
+ winui::Core::ICoreCursor** value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE put_PointerCursor(
+ winui::Core::ICoreCursor* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_PointerPosition(
+ winfoundtn::Point* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_Visible(
+ boolean* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Activate(void) {
+ // After we fire OnActivate on the View, Chrome calls us back here.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Close(void) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE GetAsyncKeyState(
+ ABI::Windows::System::VirtualKey virtualKey,
+ winui::Core::CoreVirtualKeyStates* KeyState) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE GetKeyState(
+ ABI::Windows::System::VirtualKey virtualKey,
+ winui::Core::CoreVirtualKeyStates* KeyState) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE ReleasePointerCapture(void) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE SetPointerCapture(void) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_Activated(
+ WindowActivatedHandler* handler,
+ EventRegistrationToken* pCookie) {
+ // TODO(cpu) implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_Activated(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_AutomationProviderRequested(
+ AutomationProviderHandler* handler,
+ EventRegistrationToken* cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_AutomationProviderRequested(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_CharacterReceived(
+ CharEventHandler* handler,
+ EventRegistrationToken* pCookie) {
+ // TODO(cpu) : implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_CharacterReceived(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_Closed(
+ CoreWindowEventHandler* handler,
+ EventRegistrationToken* pCookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_Closed(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_InputEnabled(
+ InputEnabledEventHandler* handler,
+ EventRegistrationToken* pCookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_InputEnabled(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_KeyDown(
+ KeyEventHandler* handler,
+ EventRegistrationToken* pCookie) {
+ // TODO(cpu): implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_KeyDown(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_KeyUp(
+ KeyEventHandler* handler,
+ EventRegistrationToken* pCookie) {
+ // TODO(cpu): implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_KeyUp(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_PointerCaptureLost(
+ PointerEventHandler* handler,
+ EventRegistrationToken* cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_PointerCaptureLost(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_PointerEntered(
+ PointerEventHandler* handler,
+ EventRegistrationToken* cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_PointerEntered(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_PointerExited(
+ PointerEventHandler* handler,
+ EventRegistrationToken* cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_PointerExited(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_PointerMoved(
+ PointerEventHandler* handler,
+ EventRegistrationToken* cookie) {
+ // TODO(cpu) : implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_PointerMoved(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_PointerPressed(
+ PointerEventHandler* handler,
+ EventRegistrationToken* cookie) {
+ // TODO(cpu): implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_PointerPressed(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_PointerReleased(
+ PointerEventHandler* handler,
+ EventRegistrationToken* cookie) {
+ // TODO(cpu): implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_PointerReleased(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_TouchHitTesting(
+ TouchHitTestHandler* handler,
+ EventRegistrationToken* pCookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_TouchHitTesting(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_PointerWheelChanged(
+ PointerEventHandler* handler,
+ EventRegistrationToken* cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_PointerWheelChanged(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_SizeChanged(
+ SizeChangedHandler* handler,
+ EventRegistrationToken* pCookie) {
+ // TODO(cpu): implement this.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_SizeChanged(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
+ VisibilityChangedHandler* handler,
+ EventRegistrationToken* pCookie) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
+ EventRegistrationToken cookie) {
+ return S_OK;
+ }
+
+ // ICoreWindowInterop implementation:
+ virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) {
+ if (!core_hwnd_)
+ return E_FAIL;
+ *hwnd = core_hwnd_;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE put_MessageHandled(
+ boolean value) {
+ return S_OK;
+ }
+
+ private:
+ HWND core_hwnd_;
+ mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher_;
+};
+
+class ActivatedEvent
+ : public mswr::RuntimeClass<winapp::Activation::IActivatedEventArgs> {
+ public:
+ ActivatedEvent(winapp::Activation::ActivationKind activation_kind)
+ : activation_kind_(activation_kind) {
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_Kind(
+ winapp::Activation::ActivationKind *value) {
+ *value = activation_kind_;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_PreviousExecutionState(
+ winapp::Activation::ApplicationExecutionState *value) {
+ *value = winapp::Activation::ApplicationExecutionState_ClosedByUser;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_SplashScreen(
+ winapp::Activation::ISplashScreen **value) {
+ return E_FAIL;
+ }
+
+ private:
+ winapp::Activation::ActivationKind activation_kind_;
+};
+
+class CoreApplicationViewEmulation
+ : public mswr::RuntimeClass<winapp::Core::ICoreApplicationView> {
+ public:
+ CoreApplicationViewEmulation() {
+ core_window_ = mswr::Make<CoreWindowEmulation>();
+ }
+
+ HRESULT Activate() {
+ if (activated_handler_) {
+ auto ae = mswr::Make<ActivatedEvent>(
+ winapp::Activation::ActivationKind_File);
+ return activated_handler_->Invoke(this, ae.Get());
+ } else {
+ return S_OK;
+ }
+ }
+
+ // ICoreApplicationView implementation:
+ virtual HRESULT STDMETHODCALLTYPE get_CoreWindow(
+ winui::Core::ICoreWindow** value) {
+ if (!core_window_)
+ return E_FAIL;
+ return core_window_.CopyTo(value);
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_Activated(
+ ActivatedHandler* handler,
+ EventRegistrationToken* token) {
+ // The real component supports multiple handles but we don't yet.
+ if (activated_handler_)
+ return E_FAIL;
+ activated_handler_ = handler;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_Activated(
+ EventRegistrationToken token) {
+ // Chrome never unregisters handlers, so we don't care about it.
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_IsMain(
+ boolean* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_IsHosted(
+ boolean* value) {
+ return S_OK;
+ }
+
+ private:
+ mswr::ComPtr<winui::Core::ICoreWindow> core_window_;
+ mswr::ComPtr<ActivatedHandler> activated_handler_;
+};
+
+class CoreApplicationWin7Emulation
+ : public mswr::RuntimeClass<winapp::Core::ICoreApplication,
+ winapp::Core::ICoreApplicationExit> {
+ public:
+ // ICoreApplication implementation:
+
+ virtual HRESULT STDMETHODCALLTYPE get_Id(
+ HSTRING* value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_Suspending(
+ winfoundtn::IEventHandler<winapp::SuspendingEventArgs*>* handler,
+ EventRegistrationToken* token) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_Suspending(
+ EventRegistrationToken token) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_Resuming(
+ winfoundtn::IEventHandler<IInspectable*>* handler,
+ EventRegistrationToken* token) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_Resuming(
+ EventRegistrationToken token) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE get_Properties(
+ winfoundtn::Collections::IPropertySet** value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE GetCurrentView(
+ winapp::Core::ICoreApplicationView** value) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Run(
+ winapp::Core::IFrameworkViewSource* viewSource) {
+ HRESULT hr = viewSource->CreateView(app_view_.GetAddressOf());
+ if (FAILED(hr))
+ return hr;
+ view_emulation_ = mswr::Make<CoreApplicationViewEmulation>();
+ hr = app_view_->Initialize(view_emulation_.Get());
+ if (FAILED(hr))
+ return hr;
+ mswr::ComPtr<winui::Core::ICoreWindow> core_window;
+ hr = view_emulation_->get_CoreWindow(core_window.GetAddressOf());
+ if (FAILED(hr))
+ return hr;
+ hr = app_view_->SetWindow(core_window.Get());
+ if (FAILED(hr))
+ return hr;
+ hr = app_view_->Load(NULL);
+ if (FAILED(hr))
+ return hr;
+ hr = view_emulation_->Activate();
+ if (FAILED(hr))
+ return hr;
+ return app_view_->Run();
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE RunWithActivationFactories(
+ winfoundtn::IGetActivationFactory* activationFactoryCallback) {
+ return S_OK;
+ }
+
+ // ICoreApplicationExit implementation:
+
+ virtual HRESULT STDMETHODCALLTYPE Exit(void) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE add_Exiting(
+ winfoundtn::IEventHandler<IInspectable*>* handler,
+ EventRegistrationToken* token) {
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE remove_Exiting(
+ EventRegistrationToken token) {
+ return S_OK;
+ }
+
+ private:
+ mswr::ComPtr<winapp::Core::IFrameworkView> app_view_;
+ mswr::ComPtr<CoreApplicationViewEmulation> view_emulation_;
+};
-extern "C" _declspec(dllexport) void SetFrameWindow(HWND window) {
- ODS("SetFrameWindow", ULONG_PTR(window));
- globals.host_window = window;
-}
-extern "C" __declspec(dllexport) const wchar_t* GetInitialUrl() {
- return L"";
+mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows7() {
+ HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ if (FAILED(hr))
+ CHECK(false);
+ return mswr::Make<CoreApplicationWin7Emulation>();
}
diff --git a/win8/viewer/metro_viewer_process_host.cc b/win8/viewer/metro_viewer_process_host.cc
index 4fa519405c..a44ea3c473 100644
--- a/win8/viewer/metro_viewer_process_host.cc
+++ b/win8/viewer/metro_viewer_process_host.cc
@@ -11,6 +11,7 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
+#include "base/process/process_handle.h"
#include "base/strings/string16.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
@@ -21,6 +22,12 @@
#include "ui/metro_viewer/metro_viewer_messages.h"
#include "win8/viewer/metro_viewer_constants.h"
+namespace {
+
+const int kViewerProcessConnectionTimeoutSecs = 60;
+
+} // namespace
+
namespace win8 {
MetroViewerProcessHost::InternalMessageFilter::InternalMessageFilter(
@@ -43,6 +50,26 @@ MetroViewerProcessHost::MetroViewerProcessHost(
}
MetroViewerProcessHost::~MetroViewerProcessHost() {
+ if (!channel_)
+ return;
+
+ base::ProcessId viewer_process_id = GetViewerProcessId();
+ channel_->Close();
+ if (message_filter_) {
+ // Wait for the viewer process to go away.
+ if (viewer_process_id != base::kNullProcessId) {
+ base::ProcessHandle viewer_process = NULL;
+ base::OpenProcessHandleWithAccess(
+ viewer_process_id,
+ PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
+ &viewer_process);
+ if (viewer_process) {
+ ::WaitForSingleObject(viewer_process, INFINITE);
+ ::CloseHandle(viewer_process);
+ }
+ }
+ channel_->RemoveFilter(message_filter_);
+ }
}
base::ProcessId MetroViewerProcessHost::GetViewerProcessId() {
@@ -57,9 +84,8 @@ bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection(
channel_connected_event_.reset(new base::WaitableEvent(false, false));
- scoped_refptr<InternalMessageFilter> message_filter(
- new InternalMessageFilter(this));
- channel_->AddFilter(message_filter);
+ message_filter_ = new InternalMessageFilter(this);
+ channel_->AddFilter(message_filter_);
base::win::ScopedComPtr<IApplicationActivationManager> activator;
HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager);
@@ -75,13 +101,9 @@ bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection(
// Having launched the viewer process, now we wait for it to connect.
bool success =
- channel_connected_event_->TimedWait(base::TimeDelta::FromSeconds(60));
+ channel_connected_event_->TimedWait(base::TimeDelta::FromSeconds(
+ kViewerProcessConnectionTimeoutSecs));
channel_connected_event_.reset();
-
- // |message_filter| is only used to signal |channel_connected_event_| above
- // and can thus be removed after |channel_connected_event_| is no longer
- // waiting.
- channel_->RemoveFilter(message_filter);
return success;
}
diff --git a/win8/viewer/metro_viewer_process_host.h b/win8/viewer/metro_viewer_process_host.h
index e156226e86..209a94cf72 100644
--- a/win8/viewer/metro_viewer_process_host.h
+++ b/win8/viewer/metro_viewer_process_host.h
@@ -96,6 +96,7 @@ class MetroViewerProcessHost : public IPC::Listener,
scoped_ptr<IPC::ChannelProxy> channel_;
scoped_ptr<base::WaitableEvent> channel_connected_event_;
+ scoped_refptr<InternalMessageFilter> message_filter_;
DISALLOW_COPY_AND_ASSIGN(MetroViewerProcessHost);
};