From 7c3b7003d5f513a2608ec6586901d6367a21b0e6 Mon Sep 17 00:00:00 2001 From: "cpu@chromium.org" Date: Wed, 24 Oct 2012 17:42:32 +0000 Subject: Split ash and non-ash metro driver code ChromeAppViewFactory now produces ChromeAppView or ChromeAppViewAsh depending on the use_aura gyp flag. The two versions have very little in common. Overt time they might share more code. BUG=151718 TEST=see bug Review URL: https://codereview.chromium.org/11233070 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163860 0039d316-1c4b-4281-b951-d872f2087c98 --- win8/metro_driver/chrome_app_view.cc | 193 +--------------- win8/metro_driver/chrome_app_view.h | 41 +--- win8/metro_driver/chrome_app_view_ash.cc | 371 +++++++++++++++++++++++++++++++ win8/metro_driver/chrome_app_view_ash.h | 69 ++++++ win8/metro_driver/devices_handler.cc | 33 --- win8/metro_driver/devices_handler.h | 18 -- win8/metro_driver/metro_driver.cc | 8 +- win8/metro_driver/metro_driver.gyp | 60 +++-- win8/metro_driver/metro_driver.h | 19 ++ win8/metro_driver/stdafx.h | 7 +- win8/metro_driver/winrt_utils.cc | 22 ++ win8/metro_driver/winrt_utils.h | 10 +- 12 files changed, 541 insertions(+), 310 deletions(-) create mode 100644 win8/metro_driver/chrome_app_view_ash.cc create mode 100644 win8/metro_driver/chrome_app_view_ash.h create mode 100644 win8/metro_driver/metro_driver.h (limited to 'win8') diff --git a/win8/metro_driver/chrome_app_view.cc b/win8/metro_driver/chrome_app_view.cc index f6fac76..9a0c5f8 100644 --- a/win8/metro_driver/chrome_app_view.cc +++ b/win8/metro_driver/chrome_app_view.cc @@ -14,19 +14,15 @@ #include "base/message_loop.h" #include "base/win/metro.h" -#include "base/threading/thread.h" -#include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_proxy.h" -#include "ipc/ipc_sender.h" #include "ui/gfx/native_widget_types.h" #include "ui/metro_viewer/metro_viewer_messages.h" // This include allows to send WM_SYSCOMMANDs to chrome. #include "chrome/app/chrome_command_ids.h" +#include "win8/metro_driver/metro_driver.h" #include "win8/metro_driver/winrt_utils.h" #include "ui/base/ui_base_switches.h" - typedef winfoundtn::ITypedEventHandler< winapp::Core::CoreApplicationView*, winapp::Activation::IActivatedEventArgs*> ActivatedHandler; @@ -299,26 +295,6 @@ void FlipFrameWindowsInternal() { } } -class ChromeChannelListener : public IPC::Listener { - public: - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { - DVLOG(1) << "Received ipc message " << message.type(); - return true; - } - - virtual void OnChannelError() OVERRIDE { - DVLOG(1) << "Channel error"; - MessageLoop::current()->Quit(); - } - - void Init(IPC::Sender* s) { - sender_ = s; - } - - private: - IPC::Sender* sender_; -}; - } // namespace HRESULT ChromeAppView::TileRequestCreateDone( @@ -627,17 +603,6 @@ void SetFullscreen(bool fullscreen) { globals.view, fullscreen)); } -BOOL CALLBACK CoreWindowFinder(HWND hwnd, LPARAM) { - char classname[128]; - if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) { - if (lstrcmpiA("Windows.UI.Core.CoreWindow", classname) == 0) { - globals.core_window = hwnd; - return FALSE; - } - } - return TRUE; -} - template void CloseSecondaryWindows(ContainerT& windows) { DVLOG(1) << "Closing secondary windows", windows.size(); @@ -674,9 +639,7 @@ DWORD WINAPI HostMainThreadProc(void*) { ChromeAppView::ChromeAppView() : osk_visible_notification_received_(false), - osk_offset_adjustment_(0), - ui_channel_(nullptr), - ui_channel_listener_(nullptr) { + osk_offset_adjustment_(0) { globals.previous_state = winapp::Activation::ApplicationExecutionState_NotRunning; } @@ -705,40 +668,6 @@ ChromeAppView::SetWindow(winui::Core::ICoreWindow* window) { HRESULT hr = url_launch_handler_.Initialize(); CheckHR(hr, "Failed to initialize url launch handler."); - -#if defined(USE_AURA) - // Register for pointer and keyboard notifications. We forward - // them to the browser process via IPC. - hr = window_->add_PointerMoved(mswr::Callback( - this, &ChromeAppView::OnPointerMoved).Get(), - &pointermoved_token_); - CheckHR(hr); - - hr = window_->add_PointerPressed(mswr::Callback( - this, &ChromeAppView::OnPointerPressed).Get(), - &pointerpressed_token_); - CheckHR(hr); - - hr = window_->add_PointerReleased(mswr::Callback( - this, &ChromeAppView::OnPointerReleased).Get(), - &pointerreleased_token_); - CheckHR(hr); - - hr = window_->add_KeyDown(mswr::Callback( - this, &ChromeAppView::OnKeyDown).Get(), - &keydown_token_); - CheckHR(hr); - - hr = window_->add_KeyUp(mswr::Callback( - this, &ChromeAppView::OnKeyUp).Get(), - &keyup_token_); - CheckHR(hr); - - // By initializing the direct 3D swap chain with the corewindow - // we can now directly blit to it from the browser process. - direct3d_helper_.Initialize(window); - DVLOG(1) << "Initialized Direct3D."; -#else // Register for size notifications. hr = window_->add_SizeChanged(mswr::Callback( this, &ChromeAppView::OnSizeChanged).Get(), @@ -783,7 +712,6 @@ ChromeAppView::SetWindow(winui::Core::ICoreWindow* window) { // The documented InputPane notifications don't fire on Windows 8 in metro // chrome. Uncomment this once we figure out why they don't fire. // RegisterInputPaneNotifications(); - hr = winrt_utils::CreateActivationFactory( RuntimeClass_Windows_UI_ViewManagement_ApplicationView, app_view_.GetAddressOf()); @@ -796,8 +724,6 @@ ChromeAppView::SetWindow(winui::Core::ICoreWindow* window) { // initialization succeed. Even if we won't be able to access devices // we still want to allow the app to start. LOG_IF(ERROR, FAILED(hr)) << "Failed to initialize devices handler."; -#endif - return S_OK; } @@ -882,31 +808,6 @@ ChromeAppView::Run() { // Announce our message loop to the world. globals.appview_msg_loop = msg_loop.message_loop_proxy(); - // The thread needs to out-live the ChannelProxy. - base::Thread thread("metro_IO_thread"); - base::Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_IO; - thread.StartWithOptions(options); - - -#if defined(USE_AURA) - // In Aura mode we create an IPC channel to the browser which should - // be already running. - ChromeChannelListener ui_channel_listener; - IPC::ChannelProxy ui_channel("viewer", - IPC::Channel::MODE_NAMED_CLIENT, - &ui_channel_listener, - thread.message_loop_proxy()); - ui_channel_listener.Init(&ui_channel); - - ui_channel_listener_ = &ui_channel_listener; - ui_channel_ = &ui_channel; - - ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface( - gfx::NativeViewId(globals.core_window))); - - DVLOG(1) << "ICoreWindow sent " << globals.core_window; -#endif // And post the task that'll do the inner Metro message pumping to it. msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); @@ -1008,15 +909,11 @@ HRESULT ChromeAppView::OnActivate(winapp::Core::ICoreApplicationView*, return S_OK; } - do { - ::Sleep(10); - ::EnumThreadWindows(globals.main_thread_id, &CoreWindowFinder, 0); - } while (globals.core_window == NULL); + globals.core_window = + winrt_utils::FindCoreWindow(globals.main_thread_id, 10); DVLOG(1) << "CoreWindow found: " << std::hex << globals.core_window; - -#if !defined(USE_AURA) if (!globals.host_thread) { DWORD chrome_ui_thread_id = 0; globals.host_thread = @@ -1038,9 +935,6 @@ HRESULT ChromeAppView::OnActivate(winapp::Core::ICoreApplicationView*, HRESULT hr = settings_handler_.Initialize(); CheckHR(hr,"Failed to initialize settings handler."); return hr; -#else - return S_OK; -#endif } // We subclass the core window for moving the associated chrome window when the @@ -1106,85 +1000,6 @@ HRESULT ChromeAppView::OnSizeChanged(winui::Core::ICoreWindow* sender, return S_OK; } -HRESULT ChromeAppView::OnPointerMoved(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args) { - metro_driver::PointerEventHandler pointer; - HRESULT hr = pointer.Init(args); - if (FAILED(hr)) - return hr; - if (!pointer.is_mouse()) - return S_OK; - - ui_channel_->Send(new MetroViewerHostMsg_MouseMoved(pointer.x(), - pointer.y(), - 0)); - return S_OK; -} - -HRESULT ChromeAppView::OnPointerPressed(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args) { - metro_driver::PointerEventHandler pointer; - HRESULT hr = pointer.Init(args); - if (FAILED(hr)) - return hr; - if (!pointer.is_mouse()) - return S_OK; - - ui_channel_->Send(new MetroViewerHostMsg_MouseButton(pointer.x(), - pointer.y(), - 1)); - return S_OK; -} - -HRESULT ChromeAppView::OnPointerReleased(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args) { - metro_driver::PointerEventHandler pointer; - HRESULT hr = pointer.Init(args); - if (FAILED(hr)) - return hr; - if (!pointer.is_mouse()) - return S_OK; - - ui_channel_->Send(new MetroViewerHostMsg_MouseButton(pointer.x(), - pointer.y(), - 0)); - return S_OK; -} - -HRESULT ChromeAppView::OnKeyDown(winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args) { - winsys::VirtualKey virtual_key; - HRESULT hr = args->get_VirtualKey(&virtual_key); - if (FAILED(hr)) - return hr; - winui::Core::CorePhysicalKeyStatus status; - hr = args->get_KeyStatus(&status); - if (FAILED(hr)) - return hr; - - ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key, - status.RepeatCount, - status.ScanCode)); - return S_OK; -} - -HRESULT ChromeAppView::OnKeyUp(winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args) { - winsys::VirtualKey virtual_key; - HRESULT hr = args->get_VirtualKey(&virtual_key); - if (FAILED(hr)) - return hr; - winui::Core::CorePhysicalKeyStatus status; - hr = args->get_KeyStatus(&status); - if (FAILED(hr)) - return hr; - - ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key, - status.RepeatCount, - status.ScanCode)); - return S_OK; -} - HRESULT ChromeAppView::OnPositionChanged(int x, int y) { DVLOG(1) << __FUNCTION__; diff --git a/win8/metro_driver/chrome_app_view.h b/win8/metro_driver/chrome_app_view.h index 3ca5e2b..248d177 100644 --- a/win8/metro_driver/chrome_app_view.h +++ b/win8/metro_driver/chrome_app_view.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_CHROME_APP_VIEW_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_CHROME_APP_VIEW_H_ +#ifndef WIN8_METRO_DRIVER_CHROME_APP_VIEW_H_ +#define WIN8_METRO_DRIVER_CHROME_APP_VIEW_H_ #include #include @@ -20,7 +20,6 @@ #include "base/synchronization/lock.h" #include "win8/metro_driver/chrome_url_launch_handler.h" #include "win8/metro_driver/devices_handler.h" -#include "win8/metro_driver/direct3d_helper.h" #include "win8/metro_driver/metro_dialog_box.h" #include "win8/metro_driver/settings_handler.h" #include "win8/metro_driver/toast_notification_handler.h" @@ -82,21 +81,6 @@ class ChromeAppView HRESULT OnSizeChanged(winui::Core::ICoreWindow* sender, winui::Core::IWindowSizeChangedEventArgs* args); - HRESULT OnPointerMoved(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args); - - HRESULT OnPointerPressed(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args); - - HRESULT OnPointerReleased(winui::Core::ICoreWindow* sender, - winui::Core::IPointerEventArgs* args); - - HRESULT OnKeyDown(winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args); - - HRESULT OnKeyUp(winui::Core::ICoreWindow* sender, - winui::Core::IKeyEventArgs* args); - HRESULT OnEdgeGestureCompleted(winui::Input::IEdgeGesture* gesture, winui::Input::IEdgeGestureEventArgs* args); @@ -130,11 +114,6 @@ class ChromeAppView EventRegistrationToken input_pane_visible_token_; EventRegistrationToken input_pane_hiding_token_; EventRegistrationToken app_exit_token_; - EventRegistrationToken pointermoved_token_; - EventRegistrationToken pointerpressed_token_; - EventRegistrationToken pointerreleased_token_; - EventRegistrationToken keydown_token_; - EventRegistrationToken keyup_token_; ChromeUrlLaunchHandler url_launch_handler_; metro_driver::DevicesHandler devices_handler_; @@ -158,20 +137,6 @@ class ChromeAppView int osk_offset_adjustment_; MetroDialogBox dialog_box_; - - metro_driver::Direct3DHelper direct3d_helper_; - - IPC::Listener* ui_channel_listener_; - IPC::ChannelProxy* ui_channel_; -}; - -class ChromeAppViewFactory - : public mswr::RuntimeClass { - public: - ChromeAppViewFactory(winapp::Core::ICoreApplication* icore_app, - LPTHREAD_START_ROUTINE host_main, - void* host_context); - IFACEMETHOD(CreateView)(winapp::Core::IFrameworkView** view); }; // This function is exported by chrome.exe. @@ -205,4 +170,4 @@ struct Globals { extern Globals globals; -#endif // CHROME_BROWSER_UI_METRO_DRIVER_CHROME_APP_VIEW_H_ +#endif // WIN8_METRO_DRIVER_CHROME_APP_VIEW_H_ diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc new file mode 100644 index 0000000..4cde83a --- /dev/null +++ b/win8/metro_driver/chrome_app_view_ash.cc @@ -0,0 +1,371 @@ +// 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 "win8/metro_driver/stdafx.h" +#include "win8/metro_driver/chrome_app_view_ash.h" + +#include + +#include "base/bind.h" +#include "base/message_loop.h" +#include "base/win/metro.h" +#include "base/threading/thread.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_sender.h" +#include "ui/metro_viewer/metro_viewer_messages.h" +#include "win8/metro_driver/metro_driver.h" +#include "win8/metro_driver/winrt_utils.h" + +typedef winfoundtn::ITypedEventHandler< + winapp::Core::CoreApplicationView*, + winapp::Activation::IActivatedEventArgs*> ActivatedHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::PointerEventArgs*> PointerEventHandler; + +typedef winfoundtn::ITypedEventHandler< + winui::Core::CoreWindow*, + winui::Core::KeyEventArgs*> KeyEventHandler; + +// This function is exported by chrome.exe. +typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info); + +// Global information used across the metro driver. +struct Globals { + LPTHREAD_START_ROUTINE host_main; + HWND core_window; + DWORD main_thread_id; + winapp::Activation::ApplicationExecutionState previous_state; + winapp::Core::ICoreApplicationExit* app_exit; + BreakpadExceptionHandler breakpad_exception_handler; +} globals; + +namespace { + +class ChromeChannelListener : public IPC::Listener { + public: + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { + DVLOG(1) << "Received ipc message " << message.type(); + return true; + } + + virtual void OnChannelError() OVERRIDE { + DVLOG(1) << "Channel error"; + MessageLoop::current()->Quit(); + } + + void Init(IPC::Sender* s) { + sender_ = s; + } + + private: + IPC::Sender* sender_; +}; + +// This class helps decoding the pointer properties of an event. +class PointerInfoHandler { + public: + PointerInfoHandler() : x_(0), y_(0), is_mouse_(false) {}; + + HRESULT Init(winui::Core::IPointerEventArgs* args) { + mswr::ComPtr pointer_point; + HRESULT hr = args->get_CurrentPoint(&pointer_point); + if (FAILED(hr)) + return hr; + + mswr::ComPtr pointer_device; + hr = pointer_point->get_PointerDevice(&pointer_device); + if (FAILED(hr)) + return hr; + + windevs::Input::PointerDeviceType device_type; + hr = pointer_device->get_PointerDeviceType(&device_type); + if (FAILED(hr)) + return hr; + + is_mouse_ = (device_type == windevs::Input::PointerDeviceType_Mouse); + winfoundtn::Point point; + hr = pointer_point->get_Position(&point); + if (FAILED(hr)) + return hr; + + x_ = point.X; + y_ = point.Y; + return S_OK; + } + + bool is_mouse() const { return is_mouse_; } + int x() const { return x_; } + int y() const { return y_; } + + private: + int x_; + int y_; + bool is_mouse_; +}; + +void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) { + // We're entering a nested message loop, let's allow dispatching + // tasks while we're in there. + MessageLoop::current()->SetNestableTasksAllowed(true); + + // Enter main core message loop. There are several ways to exit it + // Nicely: + // 1 - User action like ALT-F4. + // 2 - Calling ICoreApplicationExit::Exit(). + // 3- Posting WM_CLOSE to the core window. + HRESULT hr = dispatcher->ProcessEvents( + winui::Core::CoreProcessEventsOption + ::CoreProcessEventsOption_ProcessUntilQuit); + + // Wind down the thread's chrome message loop. + MessageLoop::current()->Quit(); +} + +} // namespace + +ChromeAppViewAsh::ChromeAppViewAsh() + : ui_channel_(nullptr), + ui_channel_listener_(nullptr) { + globals.previous_state = + winapp::Activation::ApplicationExecutionState_NotRunning; +} + +ChromeAppViewAsh::~ChromeAppViewAsh() { + DVLOG(1) << __FUNCTION__; +} + +IFACEMETHODIMP +ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) { + view_ = view; + DVLOG(1) << __FUNCTION__; + globals.main_thread_id = ::GetCurrentThreadId(); + + HRESULT hr = view_->add_Activated(mswr::Callback( + this, &ChromeAppViewAsh::OnActivate).Get(), + &activated_token_); + CheckHR(hr); + return hr; +} + +IFACEMETHODIMP +ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { + window_ = window; + DVLOG(1) << __FUNCTION__; + // Register for pointer and keyboard notifications. We forward + // them to the browser process via IPC. + HRESULT hr = window_->add_PointerMoved(mswr::Callback( + this, &ChromeAppViewAsh::OnPointerMoved).Get(), + &pointermoved_token_); + CheckHR(hr); + + hr = window_->add_PointerPressed(mswr::Callback( + this, &ChromeAppViewAsh::OnPointerPressed).Get(), + &pointerpressed_token_); + CheckHR(hr); + + hr = window_->add_PointerReleased(mswr::Callback( + this, &ChromeAppViewAsh::OnPointerReleased).Get(), + &pointerreleased_token_); + CheckHR(hr); + + hr = window_->add_KeyDown(mswr::Callback( + this, &ChromeAppViewAsh::OnKeyDown).Get(), + &keydown_token_); + CheckHR(hr); + + hr = window_->add_KeyUp(mswr::Callback( + this, &ChromeAppViewAsh::OnKeyUp).Get(), + &keyup_token_); + CheckHR(hr); + + // By initializing the direct 3D swap chain with the corewindow + // we can now directly blit to it from the browser process. + direct3d_helper_.Initialize(window); + DVLOG(1) << "Initialized Direct3D."; + return S_OK; +} + +IFACEMETHODIMP +ChromeAppViewAsh::Load(HSTRING entryPoint) { + DVLOG(1) << __FUNCTION__; + return S_OK; +} + +IFACEMETHODIMP +ChromeAppViewAsh::Run() { + DVLOG(1) << __FUNCTION__; + mswr::ComPtr dispatcher; + HRESULT hr = window_->get_Dispatcher(&dispatcher); + CheckHR(hr, "Dispatcher failed."); + + hr = window_->Activate(); + if (SUCCEEDED(hr)) { + // TODO(cpu): Draw something here. + } else { + DVLOG(1) << "Activate failed, hr=" << hr; + } + + // Create a message loop to allow message passing into this thread. + MessageLoop msg_loop(MessageLoop::TYPE_UI); + + // Create the IPC channel IO thread. It needs to out-live the ChannelProxy. + base::Thread thread("metro_IO_thread"); + base::Thread::Options options; + options.message_loop_type = MessageLoop::TYPE_IO; + thread.StartWithOptions(options); + + // In Aura mode we create an IPC channel to the browser which should + // be already running. + ChromeChannelListener ui_channel_listener; + IPC::ChannelProxy ui_channel("viewer", + IPC::Channel::MODE_NAMED_CLIENT, + &ui_channel_listener, + thread.message_loop_proxy()); + ui_channel_listener.Init(&ui_channel); + + ui_channel_listener_ = &ui_channel_listener; + ui_channel_ = &ui_channel; + + ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface( + gfx::NativeViewId(globals.core_window))); + + DVLOG(1) << "ICoreWindow sent " << globals.core_window; + + // And post the task that'll do the inner Metro message pumping to it. + msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); + msg_loop.Run(); + + DVLOG(0) << "ProcessEvents done, hr=" << hr; + return hr; +} + +IFACEMETHODIMP +ChromeAppViewAsh::Uninitialize() { + DVLOG(1) << __FUNCTION__; + window_ = nullptr; + view_ = nullptr; + return S_OK; +} + +HRESULT ChromeAppViewAsh::OnActivate(winapp::Core::ICoreApplicationView*, + winapp::Activation::IActivatedEventArgs* args) { + DVLOG(1) << __FUNCTION__; + + args->get_PreviousExecutionState(&globals.previous_state); + DVLOG(1) << "Previous Execution State: " << globals.previous_state; + + window_->Activate(); + + if (globals.previous_state == + winapp::Activation::ApplicationExecutionState_Running) { + DVLOG(1) << "Already running. Skipping rest of OnActivate."; + return S_OK; + } + + globals.core_window = + winrt_utils::FindCoreWindow(globals.main_thread_id, 10); + + DVLOG(1) << "CoreWindow found: " << std::hex << globals.core_window; + return S_OK; +} + +HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender, + winui::Core::IPointerEventArgs* args) { + PointerInfoHandler pointer; + HRESULT hr = pointer.Init(args); + if (FAILED(hr)) + return hr; + if (!pointer.is_mouse()) + return S_OK; + + ui_channel_->Send(new MetroViewerHostMsg_MouseMoved(pointer.x(), + pointer.y(), + 0)); + return S_OK; +} + +HRESULT ChromeAppViewAsh::OnPointerPressed(winui::Core::ICoreWindow* sender, + winui::Core::IPointerEventArgs* args) { + PointerInfoHandler pointer; + HRESULT hr = pointer.Init(args); + if (FAILED(hr)) + return hr; + if (!pointer.is_mouse()) + return S_OK; + + ui_channel_->Send(new MetroViewerHostMsg_MouseButton(pointer.x(), + pointer.y(), + 1)); + return S_OK; +} + +HRESULT ChromeAppViewAsh::OnPointerReleased(winui::Core::ICoreWindow* sender, + winui::Core::IPointerEventArgs* args) { + PointerInfoHandler pointer; + HRESULT hr = pointer.Init(args); + if (FAILED(hr)) + return hr; + if (!pointer.is_mouse()) + return S_OK; + + ui_channel_->Send(new MetroViewerHostMsg_MouseButton(pointer.x(), + pointer.y(), + 0)); + return S_OK; +} + +HRESULT ChromeAppViewAsh::OnKeyDown(winui::Core::ICoreWindow* sender, + winui::Core::IKeyEventArgs* args) { + winsys::VirtualKey virtual_key; + HRESULT hr = args->get_VirtualKey(&virtual_key); + if (FAILED(hr)) + return hr; + winui::Core::CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + if (FAILED(hr)) + return hr; + + ui_channel_->Send(new MetroViewerHostMsg_KeyDown(virtual_key, + status.RepeatCount, + status.ScanCode)); + return S_OK; +} + +HRESULT ChromeAppViewAsh::OnKeyUp(winui::Core::ICoreWindow* sender, + winui::Core::IKeyEventArgs* args) { + winsys::VirtualKey virtual_key; + HRESULT hr = args->get_VirtualKey(&virtual_key); + if (FAILED(hr)) + return hr; + winui::Core::CorePhysicalKeyStatus status; + hr = args->get_KeyStatus(&status); + if (FAILED(hr)) + return hr; + + ui_channel_->Send(new MetroViewerHostMsg_KeyUp(virtual_key, + status.RepeatCount, + status.ScanCode)); + return S_OK; +} + +/////////////////////////////////////////////////////////////////////////////// + +ChromeAppViewFactory::ChromeAppViewFactory( + winapp::Core::ICoreApplication* icore_app, + LPTHREAD_START_ROUTINE host_main, + void* host_context) { + mswr::ComPtr core_app(icore_app); + mswr::ComPtr app_exit; + CheckHR(core_app.As(&app_exit)); + globals.app_exit = app_exit.Detach(); +} + +IFACEMETHODIMP +ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { + *view = mswr::Make().Detach(); + return (*view) ? S_OK : E_OUTOFMEMORY; +} diff --git a/win8/metro_driver/chrome_app_view_ash.h b/win8/metro_driver/chrome_app_view_ash.h new file mode 100644 index 0000000..2379b51 --- /dev/null +++ b/win8/metro_driver/chrome_app_view_ash.h @@ -0,0 +1,69 @@ +// 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 WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ +#define WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ + +#include +#include +#include +#include + +#include "base/memory/scoped_ptr.h" +#include "win8/metro_driver/direct3d_helper.h" + +namespace IPC { + class Listener; + class ChannelProxy; +} + +class ChromeAppViewAsh + : public mswr::RuntimeClass { + public: + ChromeAppViewAsh(); + ~ChromeAppViewAsh(); + + // IViewProvider overrides. + IFACEMETHOD(Initialize)(winapp::Core::ICoreApplicationView* view); + IFACEMETHOD(SetWindow)(winui::Core::ICoreWindow* window); + IFACEMETHOD(Load)(HSTRING entryPoint); + IFACEMETHOD(Run)(); + IFACEMETHOD(Uninitialize)(); + + private: + HRESULT OnActivate(winapp::Core::ICoreApplicationView* view, + winapp::Activation::IActivatedEventArgs* args); + + HRESULT OnPointerMoved(winui::Core::ICoreWindow* sender, + winui::Core::IPointerEventArgs* args); + + HRESULT OnPointerPressed(winui::Core::ICoreWindow* sender, + winui::Core::IPointerEventArgs* args); + + HRESULT OnPointerReleased(winui::Core::ICoreWindow* sender, + winui::Core::IPointerEventArgs* args); + + HRESULT OnKeyDown(winui::Core::ICoreWindow* sender, + winui::Core::IKeyEventArgs* args); + + HRESULT OnKeyUp(winui::Core::ICoreWindow* sender, + winui::Core::IKeyEventArgs* args); + + + mswr::ComPtr window_; + mswr::ComPtr view_; + EventRegistrationToken activated_token_; + EventRegistrationToken pointermoved_token_; + EventRegistrationToken pointerpressed_token_; + EventRegistrationToken pointerreleased_token_; + EventRegistrationToken keydown_token_; + EventRegistrationToken keyup_token_; + + metro_driver::Direct3DHelper direct3d_helper_; + + IPC::Listener* ui_channel_listener_; + IPC::ChannelProxy* ui_channel_; +}; + +#endif // WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ diff --git a/win8/metro_driver/devices_handler.cc b/win8/metro_driver/devices_handler.cc index 9175885..20fd413 100644 --- a/win8/metro_driver/devices_handler.cc +++ b/win8/metro_driver/devices_handler.cc @@ -20,37 +20,4 @@ HRESULT DevicesHandler::Initialize(winui::Core::ICoreWindow* window) { return hr; } -PointerEventHandler::PointerEventHandler() { -} - -PointerEventHandler::~PointerEventHandler() { -} - -HRESULT PointerEventHandler::Init(winui::Core::IPointerEventArgs* args) { - mswr::ComPtr pointer_point; - HRESULT hr = args->get_CurrentPoint(&pointer_point); - if (FAILED(hr)) - return hr; - - mswr::ComPtr pointer_device; - hr = pointer_point->get_PointerDevice(&pointer_device); - if (FAILED(hr)) - return hr; - - windevs::Input::PointerDeviceType device_type; - hr = pointer_device->get_PointerDeviceType(&device_type); - if (FAILED(hr)) - return hr; - - is_mouse_ = (device_type == windevs::Input::PointerDeviceType_Mouse); - winfoundtn::Point point; - hr = pointer_point->get_Position(&point); - if (FAILED(hr)) - return hr; - - x_ = point.X; - y_ = point.Y; - return S_OK; -} - } // namespace metro_driver diff --git a/win8/metro_driver/devices_handler.h b/win8/metro_driver/devices_handler.h index c3623b0..fdb2226 100644 --- a/win8/metro_driver/devices_handler.h +++ b/win8/metro_driver/devices_handler.h @@ -26,24 +26,6 @@ class DevicesHandler { DISALLOW_COPY_AND_ASSIGN(DevicesHandler); }; -// This class helps decoding the pointer properties of an event. -class PointerEventHandler { - public: - PointerEventHandler(); - ~PointerEventHandler(); - - HRESULT Init(winui::Core::IPointerEventArgs* args); - - bool is_mouse() const { return is_mouse_; } - int x() const { return x_; } - int y() const { return y_; } - - private: - int x_; - int y_; - bool is_mouse_; -}; - } // namespace metro_driver #endif // CHROME_BROWSER_UI_METRO_DRIVER_DEVICES_HANDLER_H_ diff --git a/win8/metro_driver/metro_driver.cc b/win8/metro_driver/metro_driver.cc index 89bd35a..8c07d356 100644 --- a/win8/metro_driver/metro_driver.cc +++ b/win8/metro_driver/metro_driver.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "stdafx.h" +#include "win8/metro_driver/metro_driver.h" #include #include @@ -12,10 +13,13 @@ #include "base/logging.h" #include "base/logging_win.h" #include "base/win/scoped_comptr.h" -#include "win8/metro_driver/chrome_app_view.h" #include "win8/metro_driver/winrt_utils.h" #include "sandbox/win/src/sidestep/preamble_patcher.h" +#if !defined(USE_AURA) +#include "win8/metro_driver/chrome_app_view.h" +#endif + // TODO(siggi): Move this to GYP. #pragma comment(lib, "runtimeobject.lib") @@ -180,9 +184,11 @@ int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) { if (FAILED(hr)) return 1; +#if !defined(USE_AURA) // The metro specific hacks code assumes that there is only one thread active // at the moment. This better be the case or we may have race conditions. Hacks::MetroSpecificHacksInitialize(); +#endif auto view_factory = mswr::Make( core_app.Get(), thread_proc, context); diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp index e3ecf17..3379f07 100644 --- a/win8/metro_driver/metro_driver.gyp +++ b/win8/metro_driver/metro_driver.gyp @@ -35,35 +35,47 @@ '../win8.gyp:check_sdk_patch', ], 'sources': [ - 'chrome_app_view.cc', - 'chrome_app_view.h', - 'chrome_url_launch_handler.cc', - 'chrome_url_launch_handler.h', - '../delegate_execute/chrome_util.cc', - '../delegate_execute/chrome_util.h', - 'devices_handler.cc', - 'devices_handler.h', - 'direct3d_helper.cc', - 'direct3d_helper.h', - 'file_picker.h', - 'file_picker.cc', - 'metro_dialog_box.cc', - 'metro_dialog_box.h', 'metro_driver.cc', - 'print_handler.cc', - 'print_handler.h', - 'print_document_source.cc', - 'print_document_source.h', - 'secondary_tile.h', - 'secondary_tile.cc', - 'settings_handler.cc', - 'settings_handler.h', + 'metro_driver.h', 'stdafx.h', - 'toast_notification_handler.cc', - 'toast_notification_handler.h', 'winrt_utils.cc', 'winrt_utils.h', ], + 'conditions': [ + ['use_aura==1', { + 'sources': [ + 'chrome_app_view_ash.cc', + 'chrome_app_view_ash.h', + 'direct3d_helper.cc', + 'direct3d_helper.h', + ], + }, { # use_aura!=1 + 'sources': [ + 'chrome_app_view.cc', + 'chrome_app_view.h', + 'chrome_url_launch_handler.cc', + 'chrome_url_launch_handler.h', + '../delegate_execute/chrome_util.cc', + '../delegate_execute/chrome_util.h', + 'devices_handler.cc', + 'devices_handler.h', + 'file_picker.h', + 'file_picker.cc', + 'metro_dialog_box.cc', + 'metro_dialog_box.h', + 'print_handler.cc', + 'print_handler.h', + 'print_document_source.cc', + 'print_document_source.h', + 'secondary_tile.h', + 'secondary_tile.cc', + 'settings_handler.cc', + 'settings_handler.h', + 'toast_notification_handler.cc', + 'toast_notification_handler.h', + ], + }], + ], 'copies': [ { 'destination': '<(PRODUCT_DIR)', diff --git a/win8/metro_driver/metro_driver.h b/win8/metro_driver/metro_driver.h new file mode 100644 index 0000000..c4ea2ab --- /dev/null +++ b/win8/metro_driver/metro_driver.h @@ -0,0 +1,19 @@ +// 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 WIN8_METRO_DRIVER_METRO_DRIVER_H_ +#define WIN8_METRO_DRIVER_METRO_DRIVER_H_ + +#include "stdafx.h" + +class ChromeAppViewFactory + : public mswr::RuntimeClass { + public: + ChromeAppViewFactory(winapp::Core::ICoreApplication* icore_app, + LPTHREAD_START_ROUTINE host_main, + void* host_context); + IFACEMETHOD(CreateView)(winapp::Core::IFrameworkView** view); +}; + +#endif // WIN8_METRO_DRIVER_METRO_DRIVER_H_ \ No newline at end of file diff --git a/win8/metro_driver/stdafx.h b/win8/metro_driver/stdafx.h index cf4204d..a44c36f 100644 --- a/win8/metro_driver/stdafx.h +++ b/win8/metro_driver/stdafx.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_STDAFX_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_STDAFX_H_ +#ifndef WIN8_METRO_DRIVER_STDAFX_H_ +#define WIN8_METRO_DRIVER_STDAFX_H_ #include #include @@ -35,5 +35,4 @@ namespace wingfx = ABI::Windows::Graphics; namespace winui = ABI::Windows::UI; namespace winsys = ABI::Windows::System; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_STDAFX_H_ +#endif // WIN8_METRO_DRIVER_STDAFX_H_ diff --git a/win8/metro_driver/winrt_utils.cc b/win8/metro_driver/winrt_utils.cc index cfddc5e..f00011d 100644 --- a/win8/metro_driver/winrt_utils.cc +++ b/win8/metro_driver/winrt_utils.cc @@ -70,6 +70,19 @@ HRESULT Create ## Name ## Property(Type value, \ *result = 0; \ hr = S_OK + +BOOL CALLBACK CoreWindowFinder(HWND hwnd, LPARAM param) { + HWND* window = reinterpret_cast(param); + char classname[128]; + if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) { + if (lstrcmpiA("Windows.UI.Core.CoreWindow", classname) == 0) { + *window = hwnd; + return FALSE; + } + } + return TRUE; +} + } // namespace namespace winrt_utils { @@ -222,4 +235,13 @@ string16 ReadArgumentsFromPinnedTaskbarShortcut() { return L""; } +HWND FindCoreWindow(DWORD thread_id, int wait_ms) { + HWND window = NULL; + do { + ::Sleep(wait_ms); + ::EnumThreadWindows(thread_id, &CoreWindowFinder, LPARAM(&window)); + } while (window == NULL); + return window; +} + } // namespace winrt_utils diff --git a/win8/metro_driver/winrt_utils.h b/win8/metro_driver/winrt_utils.h index 28f1ead..1ad0a05 100644 --- a/win8/metro_driver/winrt_utils.h +++ b/win8/metro_driver/winrt_utils.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_METRO_DRIVER_WINRT_UTILS_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_WINRT_UTILS_H_ +#ifndef WIN8_METRO_DRIVER_WINRT_UTILS_H_ +#define WIN8_METRO_DRIVER_WINRT_UTILS_H_ #include @@ -55,6 +55,10 @@ HRESULT CompareProperties( // empty string on failure. string16 ReadArgumentsFromPinnedTaskbarShortcut(); +// Looks for a Window with the right class name that belongs to |thread_id| +// thread. It loops forever looking for it, waiting |wait_ms| between loops. +HWND FindCoreWindow(DWORD thread_id, int wait_ms); + } // namespace winrt_utils -#endif // CHROME_BROWSER_UI_METRO_DRIVER_WINRT_UTILS_H_ +#endif // WIN8_METRO_DRIVER_WINRT_UTILS_H_ -- cgit v1.1