From 0b477f60f07224c4bafcf959ac66c7c22c86bfc5 Mon Sep 17 00:00:00 2001 From: "cpu@chromium.org" Date: Thu, 27 Mar 2014 21:08:57 +0000 Subject: Second part of porting Chrome Ash to Windows 7 This CL adds more meat to all the interfaces and gets ChromeAppViewAsh to work all the Way to the Run() method, including the DirectX initialization. First part with rationale: https://codereview.chromium.org/199843004/ NOTRY=true BUG=356475 TEST=none Review URL: https://codereview.chromium.org/211863003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@259984 0039d316-1c4b-4281-b951-d872f2087c98 --- win8/metro_driver/chrome_app_view_ash.cc | 42 ++++--- win8/metro_driver/direct3d_helper.cc | 47 ++++++-- win8/metro_driver/metro_driver_win7.cc | 192 +++++++++++++++++++++++++++---- 3 files changed, 228 insertions(+), 53 deletions(-) (limited to 'win8') diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc index dc5923c..8e1f0e6 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 dispatcher; - hr = window_->get_Dispatcher(&dispatcher); + hr = window_->get_Dispatcher(dispatcher.GetAddressOf()); CheckHR(hr, "Get Dispatcher failed."); mswr::ComPtr accelerator_keys; @@ -602,21 +603,23 @@ ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { &window_activated_token_); CheckHR(hr); - // Register for edge gesture notifications. - mswr::ComPtr edge_gesture_statics; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Input_EdgeGesture, - edge_gesture_statics.GetAddressOf()); - CheckHR(hr); - - mswr::ComPtr edge_gesture; - hr = edge_gesture_statics->GetForCurrentView(&edge_gesture); - CheckHR(hr); - - hr = edge_gesture->add_Completed(mswr::Callback( - 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 edge_gesture_statics; + hr = winrt_utils::CreateActivationFactory( + RuntimeClass_Windows_UI_Input_EdgeGesture, + edge_gesture_statics.GetAddressOf()); + CheckHR(hr); + + mswr::ComPtr edge_gesture; + hr = edge_gesture_statics->GetForCurrentView(&edge_gesture); + CheckHR(hr); + + hr = edge_gesture->add_Completed(mswr::Callback( + 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 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 056e84b..d0c30cf 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 +#include #include 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(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(window_), + &swap_chain_desc, + nullptr, + &swap_chain_)); + } else { + // On Win7 we need the raw HWND to create the Swapchain. + mswr::ComPtr 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_win7.cc b/win8/metro_driver/metro_driver_win7.cc index 56d6c05..2e5aba7 100644 --- a/win8/metro_driver/metro_driver_win7.cc +++ b/win8/metro_driver/metro_driver_win7.cc @@ -15,14 +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); break; default: - return DefWindowProc(hwnd, message, wparam, lparam); + return ::DefWindowProc(hwnd, message, wparam, lparam); } return 0; } @@ -46,8 +50,8 @@ HWND CreateMetroTopLevelWindow() { HWND hwnd = ::CreateWindowExW(0, MAKEINTATOM(::RegisterClassExW(&wcex)), L"metro_win7", - WS_POPUP, - 0, 0, 0, 0, + WS_POPUP | WS_VISIBLE, + 0, 0, 1024, 1024, NULL, NULL, hInst, NULL); return hwnd; } @@ -97,6 +101,10 @@ 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 @@ -114,37 +122,105 @@ typedef winfoundtn::ITypedEventHandler< // ICoreApplication ICoreApplicationView // | // v -// ICoreWindow ----> ICoreWindowInterop -// | -// | -// V -// real HWND +// 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, winui::Core::ICoreWindow, ICoreWindowInterop> { public: + CoreWindowEmulation() : core_hwnd_(NULL) { + dispatcher_ = mswr::Make(); + core_hwnd_ = CreateMetroTopLevelWindow(); + } + + ~CoreWindowEmulation() { + ::DestroyWindow(core_hwnd_); + } + // ICoreWindow implementation: virtual HRESULT STDMETHODCALLTYPE get_AutomationHostProvider( - IInspectable **value) { + 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) { + winfoundtn::Collections::IPropertySet** value) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE get_Dispatcher( - winui::Core::ICoreDispatcher **value) { - return S_OK; + winui::Core::ICoreDispatcher** value) { + return dispatcher_.CopyTo(value); } virtual HRESULT STDMETHODCALLTYPE get_FlowDirection( @@ -168,7 +244,7 @@ class CoreWindowEmulation } virtual HRESULT STDMETHODCALLTYPE get_PointerCursor( - winui::Core::ICoreCursor **value) { + winui::Core::ICoreCursor** value) { return S_OK; } @@ -188,6 +264,7 @@ class CoreWindowEmulation } virtual HRESULT STDMETHODCALLTYPE Activate(void) { + // After we fire OnActivate on the View, Chrome calls us back here. return S_OK; } @@ -218,6 +295,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_Activated( WindowActivatedHandler* handler, EventRegistrationToken* pCookie) { + // TODO(cpu) implement this. return S_OK; } @@ -240,6 +318,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_CharacterReceived( CharEventHandler* handler, EventRegistrationToken* pCookie) { + // TODO(cpu) : implement this. return S_OK; } @@ -273,6 +352,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_KeyDown( KeyEventHandler* handler, EventRegistrationToken* pCookie) { + // TODO(cpu): implement this. return S_OK; } @@ -284,6 +364,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_KeyUp( KeyEventHandler* handler, EventRegistrationToken* pCookie) { + // TODO(cpu): implement this. return S_OK; } @@ -328,6 +409,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_PointerMoved( PointerEventHandler* handler, EventRegistrationToken* cookie) { + // TODO(cpu) : implement this. return S_OK; } @@ -339,6 +421,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_PointerPressed( PointerEventHandler* handler, EventRegistrationToken* cookie) { + // TODO(cpu): implement this. return S_OK; } @@ -350,6 +433,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_PointerReleased( PointerEventHandler* handler, EventRegistrationToken* cookie) { + // TODO(cpu): implement this. return S_OK; } @@ -383,6 +467,7 @@ class CoreWindowEmulation virtual HRESULT STDMETHODCALLTYPE add_SizeChanged( SizeChangedHandler* handler, EventRegistrationToken* pCookie) { + // TODO(cpu): implement this. return S_OK; } @@ -403,8 +488,10 @@ class CoreWindowEmulation } // ICoreWindowInterop implementation: - virtual HRESULT STDMETHODCALLTYPE get_WindowHandle( - HWND *hwnd) { + virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) { + if (!core_hwnd_) + return E_FAIL; + *hwnd = core_hwnd_; return S_OK; } @@ -413,6 +500,37 @@ class CoreWindowEmulation return S_OK; } + private: + HWND core_hwnd_; + mswr::ComPtr dispatcher_; +}; + +class ActivatedEvent + : public mswr::RuntimeClass { + 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 @@ -422,22 +540,37 @@ class CoreApplicationViewEmulation core_window_ = mswr::Make(); } - virtual HRESULT STDMETHODCALLTYPE get_CoreWindow( - winui::Core::ICoreWindow **value) { - if (!core_window_) - return E_FAIL; - *value = core_window_.Get(); - return S_OK; - } + HRESULT Activate() { + if (activated_handler_) { + auto ae = mswr::Make( + 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; } @@ -453,6 +586,7 @@ class CoreApplicationViewEmulation private: mswr::ComPtr core_window_; + mswr::ComPtr activated_handler_; }; class CoreApplicationWin7Emulation @@ -512,7 +646,15 @@ class CoreApplicationWin7Emulation if (FAILED(hr)) return hr; hr = app_view_->SetWindow(core_window.Get()); - return hr; + 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( @@ -539,7 +681,7 @@ class CoreApplicationWin7Emulation private: mswr::ComPtr app_view_; - mswr::ComPtr view_emulation_; + mswr::ComPtr view_emulation_; }; -- cgit v1.1