Roll WebRTC 8613:8622, Libjingle 8611:8616
[chromium-blink-merge.git] / win8 / metro_driver / metro_driver_win7.cc
blobd5496d6cbeb905a0e0b4bca3de83629ceeeb4149
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "stdafx.h"
6 #include <corewindow.h>
7 #include <shobjidl.h>
9 #include "base/logging.h"
10 #include "base/profiler/scoped_tracker.h"
11 #include "ui/gfx/geometry/safe_integer_conversions.h"
12 #include "ui/gfx/win/msg_util.h"
14 #pragma comment(lib, "shell32.lib")
16 EXTERN_C IMAGE_DOS_HEADER __ImageBase;
17 // Even though we only create a single window, we need to keep this
18 // count because of the hidden window used by the UI message loop of
19 // the metro viewer.
20 int g_window_count = 0;
22 const wchar_t kAshWin7AppId[] = L"Google.Chrome.AshWin7.1";
23 const wchar_t kAshWin7CoreWindowHandler[] = L"CoreWindowHandler";
24 extern float GetModernUIScale();
25 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam,
26 LPARAM lparam);
28 HWND CreateMetroTopLevelWindow(const RECT& work_area) {
29 HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase);
30 WNDCLASSEXW wcex;
31 wcex.cbSize = sizeof(wcex);
32 wcex.style = CS_HREDRAW | CS_VREDRAW;
33 wcex.lpfnWndProc = WndProc;
34 wcex.cbClsExtra = 0;
35 wcex.cbWndExtra = 0;
36 wcex.hInstance = hInst;
37 wcex.hIcon = LoadIcon(::GetModuleHandle(NULL), L"IDR_MAINFRAME");
38 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
39 wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1);
40 wcex.lpszMenuName = 0;
41 wcex.lpszClassName = L"Windows.UI.Core.CoreWindow";
42 wcex.hIconSm = LoadIcon(::GetModuleHandle(NULL), L"IDR_MAINFRAME");
44 HWND hwnd = ::CreateWindowExW(0,
45 MAKEINTATOM(::RegisterClassExW(&wcex)),
46 L"metro_win7",
47 WS_POPUP | WS_VISIBLE | WS_MINIMIZEBOX,
48 work_area.top, work_area.left,
49 work_area.right, work_area.bottom,
50 NULL, NULL, hInst, NULL);
51 return hwnd;
54 typedef winfoundtn::ITypedEventHandler<
55 winapp::Core::CoreApplicationView*,
56 winapp::Activation::IActivatedEventArgs*> ActivatedHandler;
58 typedef winfoundtn::ITypedEventHandler<
59 winui::Core::CoreWindow*,
60 winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler;
62 typedef winfoundtn::ITypedEventHandler<
63 winui::Core::CoreWindow*,
64 winui::Core::AutomationProviderRequestedEventArgs*>
65 AutomationProviderHandler;
67 typedef winfoundtn::ITypedEventHandler<
68 winui::Core::CoreWindow*,
69 winui::Core::CharacterReceivedEventArgs*> CharEventHandler;
71 typedef winfoundtn::ITypedEventHandler<
72 winui::Core::CoreWindow*,
73 winui::Core::CoreWindowEventArgs*> CoreWindowEventHandler;
75 typedef winfoundtn::ITypedEventHandler<
76 winui::Core::CoreWindow*,
77 winui::Core::InputEnabledEventArgs*> InputEnabledEventHandler;
79 typedef winfoundtn::ITypedEventHandler<
80 winui::Core::CoreWindow*,
81 winui::Core::KeyEventArgs*> KeyEventHandler;
83 typedef winfoundtn::ITypedEventHandler<
84 winui::Core::CoreWindow*,
85 winui::Core::PointerEventArgs*> PointerEventHandler;
87 typedef winfoundtn::ITypedEventHandler<
88 winui::Core::CoreWindow*,
89 winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler;
91 typedef winfoundtn::ITypedEventHandler<
92 winui::Core::CoreWindow*,
93 winui::Core::TouchHitTestingEventArgs*> TouchHitTestHandler;
95 typedef winfoundtn::ITypedEventHandler<
96 winui::Core::CoreWindow*,
97 winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler;
99 typedef winfoundtn::ITypedEventHandler<
100 winui::Core::CoreDispatcher*,
101 winui::Core::AcceleratorKeyEventArgs*> AcceleratorKeyEventHandler;
103 // This interface is implemented by classes which handle mouse and keyboard
104 // input.
105 class InputHandler {
106 public:
107 InputHandler() {}
108 virtual ~InputHandler() {}
110 virtual bool HandleKeyboardMessage(const MSG& msg) = 0;
111 virtual bool HandleMouseMessage(const MSG& msg) = 0;
113 private:
114 DISALLOW_COPY_AND_ASSIGN(InputHandler);
117 // This class implements the winrt interfaces corresponding to mouse input.
118 class MouseEvent : public mswr::RuntimeClass<
119 winui::Core::IPointerEventArgs,
120 winui::Input::IPointerPoint,
121 winui::Input::IPointerPointProperties,
122 windevs::Input::IPointerDevice> {
123 public:
124 MouseEvent(const MSG& msg)
125 : msg_(msg) {
128 // IPointerEventArgs implementation.
129 virtual HRESULT STDMETHODCALLTYPE get_CurrentPoint(
130 winui::Input::IPointerPoint** point) {
131 return QueryInterface(winui::Input::IID_IPointerPoint,
132 reinterpret_cast<void**>(point));
135 virtual HRESULT STDMETHODCALLTYPE get_KeyModifiers(
136 winsys::VirtualKeyModifiers* modifiers) {
137 return E_NOTIMPL;
140 virtual HRESULT STDMETHODCALLTYPE GetIntermediatePoints(
141 winfoundtn::Collections::IVector<winui::Input::PointerPoint*>** points) {
142 return E_NOTIMPL;
145 // IPointerPoint implementation.
146 virtual HRESULT STDMETHODCALLTYPE get_PointerDevice(
147 windevs::Input::IPointerDevice** pointer_device) {
148 return QueryInterface(windevs::Input::IID_IPointerDevice,
149 reinterpret_cast<void**>(pointer_device));
152 virtual HRESULT STDMETHODCALLTYPE get_Position(winfoundtn::Point* position) {
153 static float scale = GetModernUIScale();
154 // Scale down the points here as they are scaled up on the other side.
155 position->X = gfx::ToRoundedInt(CR_GET_X_LPARAM(msg_.lParam) / scale);
156 position->Y = gfx::ToRoundedInt(CR_GET_Y_LPARAM(msg_.lParam) / scale);
157 return S_OK;
160 virtual HRESULT STDMETHODCALLTYPE get_PointerId(uint32* pointer_id) {
161 // TODO(ananta)
162 // Implement this properly.
163 *pointer_id = 1;
164 return S_OK;
167 virtual HRESULT STDMETHODCALLTYPE get_Timestamp(uint64* timestamp) {
168 *timestamp = msg_.time;
169 return S_OK;
172 virtual HRESULT STDMETHODCALLTYPE get_Properties(
173 winui::Input::IPointerPointProperties** properties) {
174 return QueryInterface(winui::Input::IID_IPointerPointProperties,
175 reinterpret_cast<void**>(properties));
178 virtual HRESULT STDMETHODCALLTYPE get_RawPosition(
179 winfoundtn::Point* position) {
180 return E_NOTIMPL;
183 virtual HRESULT STDMETHODCALLTYPE get_FrameId(uint32* frame_id) {
184 return E_NOTIMPL;
187 virtual HRESULT STDMETHODCALLTYPE get_IsInContact(boolean* in_contact) {
188 return E_NOTIMPL;
191 // IPointerPointProperties implementation.
192 virtual HRESULT STDMETHODCALLTYPE get_PointerUpdateKind(
193 winui::Input::PointerUpdateKind* update_kind) {
194 // TODO(ananta)
195 // There is no WM_POINTERUPDATE equivalent on Windows 7. Look into
196 // equivalents.
197 if (msg_.message == WM_LBUTTONDOWN) {
198 *update_kind = winui::Input::PointerUpdateKind_LeftButtonPressed;
199 } else if (msg_.message == WM_RBUTTONDOWN) {
200 *update_kind = winui::Input::PointerUpdateKind_RightButtonPressed;
201 } else if (msg_.message == WM_MBUTTONDOWN) {
202 *update_kind = winui::Input::PointerUpdateKind_MiddleButtonPressed;
203 } else if (msg_.message == WM_LBUTTONUP) {
204 *update_kind = winui::Input::PointerUpdateKind_LeftButtonReleased;
205 } else if (msg_.message == WM_RBUTTONUP) {
206 *update_kind = winui::Input::PointerUpdateKind_RightButtonReleased;
207 } else if (msg_.message == WM_MBUTTONUP) {
208 *update_kind = winui::Input::PointerUpdateKind_MiddleButtonReleased;
210 return S_OK;
213 virtual HRESULT STDMETHODCALLTYPE get_IsLeftButtonPressed(
214 boolean* left_button_pressed) {
215 *left_button_pressed = msg_.wParam & MK_LBUTTON ? true : false;
216 return S_OK;
219 virtual HRESULT STDMETHODCALLTYPE get_IsRightButtonPressed(
220 boolean* right_button_pressed) {
221 *right_button_pressed = msg_.wParam & MK_RBUTTON ? true : false;
222 return S_OK;
225 virtual HRESULT STDMETHODCALLTYPE get_IsMiddleButtonPressed(
226 boolean* middle_button_pressed) {
227 *middle_button_pressed = msg_.wParam & MK_MBUTTON ? true : false;
228 return S_OK;
231 virtual HRESULT STDMETHODCALLTYPE get_IsHorizontalMouseWheel(
232 boolean* is_horizontal_mouse_wheel) {
233 *is_horizontal_mouse_wheel =
234 (msg_.message == WM_MOUSEHWHEEL) ? true : false;
235 return S_OK;
238 virtual HRESULT STDMETHODCALLTYPE get_MouseWheelDelta(int* delta) {
239 if (msg_.message == WM_MOUSEWHEEL || msg_.message == WM_MOUSEHWHEEL) {
240 *delta = GET_WHEEL_DELTA_WPARAM(msg_.wParam);
241 return S_OK;
242 } else {
243 return S_FALSE;
247 virtual HRESULT STDMETHODCALLTYPE get_Pressure(float* pressure) {
248 return E_NOTIMPL;
251 virtual HRESULT STDMETHODCALLTYPE get_IsInverted(boolean* inverted) {
252 return E_NOTIMPL;
255 virtual HRESULT STDMETHODCALLTYPE get_IsEraser(boolean* is_eraser) {
256 return E_NOTIMPL;
259 virtual HRESULT STDMETHODCALLTYPE get_Orientation(float* orientation) {
260 return E_NOTIMPL;
263 virtual HRESULT STDMETHODCALLTYPE get_XTilt(float* x_tilt) {
264 return E_NOTIMPL;
267 virtual HRESULT STDMETHODCALLTYPE get_YTilt(float* y_tilt) {
268 return E_NOTIMPL;
271 virtual HRESULT STDMETHODCALLTYPE get_Twist(float* twist) {
272 return E_NOTIMPL;
275 virtual HRESULT STDMETHODCALLTYPE get_ContactRect(winfoundtn::Rect* rect) {
276 return E_NOTIMPL;
279 virtual HRESULT STDMETHODCALLTYPE get_ContactRectRaw(winfoundtn::Rect* rect) {
280 return E_NOTIMPL;
283 virtual HRESULT STDMETHODCALLTYPE get_TouchConfidence(boolean* confidence) {
284 return E_NOTIMPL;
287 virtual HRESULT STDMETHODCALLTYPE get_IsPrimary(boolean* is_primary) {
288 return E_NOTIMPL;
291 virtual HRESULT STDMETHODCALLTYPE get_IsInRange(boolean* is_in_range) {
292 return E_NOTIMPL;
295 virtual HRESULT STDMETHODCALLTYPE get_IsCanceled(boolean* is_canceled) {
296 return E_NOTIMPL;
299 virtual HRESULT STDMETHODCALLTYPE get_IsBarrelButtonPressed(
300 boolean* is_barrel_button_pressed) {
301 return E_NOTIMPL;
304 virtual HRESULT STDMETHODCALLTYPE get_IsXButton1Pressed(
305 boolean* is_xbutton1_pressed) {
306 return E_NOTIMPL;
309 virtual HRESULT STDMETHODCALLTYPE get_IsXButton2Pressed(
310 boolean* is_xbutton2_pressed) {
311 return E_NOTIMPL;
314 virtual HRESULT STDMETHODCALLTYPE HasUsage(uint32 usage_page,
315 uint32 usage_id,
316 boolean* has_usage) {
317 return E_NOTIMPL;
320 virtual HRESULT STDMETHODCALLTYPE GetUsageValue(uint32 usage_page,
321 uint32 usage_id,
322 int32* usage_value) {
323 return E_NOTIMPL;
326 // IPointerDevice implementation.
327 virtual HRESULT STDMETHODCALLTYPE get_PointerDeviceType(
328 windevs::Input::PointerDeviceType* device_type) {
329 if (msg_.message == WM_TOUCH) {
330 *device_type = windevs::Input::PointerDeviceType_Touch;
331 } else {
332 *device_type = windevs::Input::PointerDeviceType_Mouse;
334 return S_OK;
337 virtual HRESULT STDMETHODCALLTYPE get_IsIntegrated(boolean* is_integrated) {
338 return E_NOTIMPL;
341 virtual HRESULT STDMETHODCALLTYPE get_MaxContacts(uint32* contacts) {
342 return E_NOTIMPL;
345 virtual HRESULT STDMETHODCALLTYPE get_PhysicalDeviceRect(
346 winfoundtn::Rect* rect) {
347 return E_NOTIMPL;
350 virtual HRESULT STDMETHODCALLTYPE get_ScreenRect(winfoundtn::Rect* rect) {
351 return E_NOTIMPL;
354 virtual HRESULT STDMETHODCALLTYPE get_SupportedUsages(
355 winfoundtn::Collections::IVectorView<
356 windevs::Input::PointerDeviceUsage>** usages) {
357 return E_NOTIMPL;
360 private:
361 MSG msg_;
363 DISALLOW_COPY_AND_ASSIGN(MouseEvent);
366 // This class implements the winrt interfaces needed to support keyboard
367 // character and system character messages.
368 class KeyEvent : public mswr::RuntimeClass<
369 winui::Core::IKeyEventArgs,
370 winui::Core::ICharacterReceivedEventArgs,
371 winui::Core::IAcceleratorKeyEventArgs> {
372 public:
373 KeyEvent(const MSG& msg)
374 : msg_(msg) {}
376 // IKeyEventArgs implementation.
377 virtual HRESULT STDMETHODCALLTYPE get_VirtualKey(
378 winsys::VirtualKey* virtual_key) {
379 *virtual_key = static_cast<winsys::VirtualKey>(msg_.wParam);
380 return S_OK;
383 virtual HRESULT STDMETHODCALLTYPE get_KeyStatus(
384 winui::Core::CorePhysicalKeyStatus* key_status) {
385 // As per msdn documentation for the keyboard messages.
386 key_status->RepeatCount = msg_.lParam & 0x0000FFFF;
387 key_status->ScanCode = (msg_.lParam >> 16) & 0x00FF;
388 key_status->IsExtendedKey = (msg_.lParam & (1 << 24));
389 key_status->IsMenuKeyDown = (msg_.lParam & (1 << 29));
390 key_status->WasKeyDown = (msg_.lParam & (1 << 30));
391 key_status->IsKeyReleased = (msg_.lParam & (1 << 31));
392 return S_OK;
395 // ICharacterReceivedEventArgs implementation.
396 virtual HRESULT STDMETHODCALLTYPE get_KeyCode(uint32* key_code) {
397 *key_code = msg_.wParam;
398 return S_OK;
401 // IAcceleratorKeyEventArgs implementation.
402 virtual HRESULT STDMETHODCALLTYPE get_EventType(
403 winui::Core::CoreAcceleratorKeyEventType* event_type) {
404 if (msg_.message == WM_SYSKEYDOWN) {
405 *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown;
406 } else if (msg_.message == WM_SYSKEYUP) {
407 *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp;
408 } else if (msg_.message == WM_SYSCHAR) {
409 *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemCharacter;
411 return S_OK;
414 private:
415 MSG msg_;
418 // The following classes are the emulation of the WinRT system as exposed
419 // to metro applications. There is one application (ICoreApplication) which
420 // contains a series of Views (ICoreApplicationView) each one of them
421 // containing a CoreWindow which represents a surface that can drawn to
422 // and that receives events.
424 // Here is the general dependency hierachy in terms of interfaces:
426 // IFrameworkViewSource --> IFrameworkView
427 // ^ |
428 // | | metro app
429 // ---------------------------------------------------------------------
430 // | | winRT system
431 // | v
432 // ICoreApplication ICoreApplicationView
433 // |
434 // v
435 // ICoreWindow -----> ICoreWindowInterop
436 // | |
437 // | |
438 // v V
439 // ICoreDispatcher <==> real HWND
441 class CoreDispatcherEmulation :
442 public mswr::RuntimeClass<
443 winui::Core::ICoreDispatcher,
444 winui::Core::ICoreAcceleratorKeys> {
445 public:
446 CoreDispatcherEmulation(InputHandler* input_handler)
447 : input_handler_(input_handler),
448 accelerator_key_event_handler_(NULL) {}
450 // ICoreDispatcher implementation:
451 virtual HRESULT STDMETHODCALLTYPE get_HasThreadAccess(boolean* value) {
452 return S_OK;
455 virtual HRESULT STDMETHODCALLTYPE ProcessEvents(
456 winui::Core::CoreProcessEventsOption options) {
457 // We don't support the other message pump modes. So we basically enter a
458 // traditional message loop that we only exit a teardown.
459 if (options != winui::Core::CoreProcessEventsOption_ProcessUntilQuit)
460 return E_FAIL;
462 MSG msg = {0};
463 while((::GetMessage(&msg, NULL, 0, 0) != 0) && g_window_count > 0) {
464 ProcessInputMessage(msg);
465 ::TranslateMessage(&msg);
466 ::DispatchMessage(&msg);
468 // TODO(cpu): figure what to do with msg.WParam which we would normally
469 // return here.
470 return S_OK;
473 virtual HRESULT STDMETHODCALLTYPE RunAsync(
474 winui::Core::CoreDispatcherPriority priority,
475 winui::Core::IDispatchedHandler *agileCallback,
476 ABI::Windows::Foundation::IAsyncAction** asyncAction) {
477 return S_OK;
480 virtual HRESULT STDMETHODCALLTYPE RunIdleAsync(
481 winui::Core::IIdleDispatchedHandler *agileCallback,
482 winfoundtn::IAsyncAction** asyncAction) {
483 return S_OK;
486 // ICoreAcceleratorKeys implementation:
487 virtual HRESULT STDMETHODCALLTYPE add_AcceleratorKeyActivated(
488 AcceleratorKeyEventHandler* handler,
489 EventRegistrationToken *pCookie) {
490 accelerator_key_event_handler_ = handler;
491 accelerator_key_event_handler_->AddRef();
492 return S_OK;
495 virtual HRESULT STDMETHODCALLTYPE remove_AcceleratorKeyActivated(
496 EventRegistrationToken cookie) {
497 accelerator_key_event_handler_->Release();
498 accelerator_key_event_handler_ = NULL;
499 return S_OK;
502 private:
503 bool ProcessInputMessage(const MSG& msg) {
504 // Poor man's way of dispatching input events.
505 bool ret = false;
506 if (input_handler_) {
507 if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) {
508 if ((msg.message == WM_SYSKEYDOWN) || (msg.message == WM_SYSKEYUP) ||
509 msg.message == WM_SYSCHAR) {
510 ret = HandleSystemKeys(msg);
511 } else {
512 ret = input_handler_->HandleKeyboardMessage(msg);
514 } else if ((msg.message >= WM_MOUSEFIRST) &&
515 (msg.message <= WM_MOUSELAST)) {
516 ret = input_handler_->HandleMouseMessage(msg);
519 return ret;
522 bool HandleSystemKeys(const MSG& msg) {
523 mswr::ComPtr<winui::Core::IAcceleratorKeyEventArgs> event_args;
524 event_args = mswr::Make<KeyEvent>(msg);
525 accelerator_key_event_handler_->Invoke(this, event_args.Get());
526 return true;
529 InputHandler* input_handler_;
530 AcceleratorKeyEventHandler* accelerator_key_event_handler_;
533 class CoreWindowEmulation
534 : public mswr::RuntimeClass<
535 mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>,
536 winui::Core::ICoreWindow, ICoreWindowInterop>,
537 public InputHandler {
538 public:
539 CoreWindowEmulation(winapp::Core::IFrameworkView* app_view)
540 : core_hwnd_(NULL),
541 mouse_moved_handler_(NULL),
542 mouse_capture_lost_handler_(NULL),
543 mouse_pressed_handler_(NULL),
544 mouse_released_handler_(NULL),
545 mouse_entered_handler_(NULL),
546 mouse_exited_handler_(NULL),
547 mouse_wheel_changed_handler_(NULL),
548 key_down_handler_(NULL),
549 key_up_handler_(NULL),
550 character_received_handler_(NULL),
551 app_view_(app_view),
552 window_activated_handler_(NULL) {
553 dispatcher_ = mswr::Make<CoreDispatcherEmulation>(this);
555 // Unless we select our own AppUserModelID the shell might confuse us
556 // with the app launcher one and we get the wrong taskbar button and icon.
557 ::SetCurrentProcessExplicitAppUserModelID(kAshWin7AppId);
559 RECT work_area = {0};
560 ::SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
561 if (::IsDebuggerPresent()) {
562 work_area.top = 0;
563 work_area.left = 0;
564 work_area.right = 1600;
565 work_area.bottom = 900;
568 core_hwnd_ = CreateMetroTopLevelWindow(work_area);
569 ::SetProp(core_hwnd_, kAshWin7CoreWindowHandler, this);
572 ~CoreWindowEmulation() {
573 if (core_hwnd_) {
574 ::RemoveProp(core_hwnd_, kAshWin7CoreWindowHandler);
575 ::DestroyWindow(core_hwnd_);
579 // ICoreWindow implementation:
580 virtual HRESULT STDMETHODCALLTYPE get_AutomationHostProvider(
581 IInspectable** value) override {
582 return S_OK;
585 virtual HRESULT STDMETHODCALLTYPE get_Bounds(
586 winfoundtn::Rect* value) override {
587 RECT rect;
588 if (!::GetClientRect(core_hwnd_, &rect))
589 return E_FAIL;
590 value->Width = rect.right;
591 value->Height = rect.bottom;
592 return S_OK;
595 virtual HRESULT STDMETHODCALLTYPE get_CustomProperties(
596 winfoundtn::Collections::IPropertySet** value) override {
597 return S_OK;
600 virtual HRESULT STDMETHODCALLTYPE get_Dispatcher(
601 winui::Core::ICoreDispatcher** value) override {
602 return dispatcher_.CopyTo(value);
605 virtual HRESULT STDMETHODCALLTYPE get_FlowDirection(
606 winui::Core::CoreWindowFlowDirection* value) override {
607 return S_OK;
610 virtual HRESULT STDMETHODCALLTYPE put_FlowDirection(
611 winui::Core::CoreWindowFlowDirection value) override {
612 return S_OK;
615 virtual HRESULT STDMETHODCALLTYPE get_IsInputEnabled(
616 boolean* value) override {
617 return S_OK;
620 virtual HRESULT STDMETHODCALLTYPE put_IsInputEnabled(
621 boolean value) override {
622 return S_OK;
625 virtual HRESULT STDMETHODCALLTYPE get_PointerCursor(
626 winui::Core::ICoreCursor** value) override {
627 return S_OK;
630 virtual HRESULT STDMETHODCALLTYPE put_PointerCursor(
631 winui::Core::ICoreCursor* value) override {
632 return S_OK;
635 virtual HRESULT STDMETHODCALLTYPE get_PointerPosition(
636 winfoundtn::Point* value) override {
637 return S_OK;
640 virtual HRESULT STDMETHODCALLTYPE get_Visible(
641 boolean* value) override {
642 return S_OK;
645 virtual HRESULT STDMETHODCALLTYPE Activate(void) override {
646 // After we fire OnActivate on the View, Chrome calls us back here.
647 return S_OK;
650 virtual HRESULT STDMETHODCALLTYPE Close(void) override {
651 ::PostMessage(core_hwnd_, WM_CLOSE, 0, 0);
652 core_hwnd_ = NULL;
653 return S_OK;
656 virtual HRESULT STDMETHODCALLTYPE GetAsyncKeyState(
657 ABI::Windows::System::VirtualKey virtualKey,
658 winui::Core::CoreVirtualKeyStates* KeyState) override {
659 return S_OK;
662 virtual HRESULT STDMETHODCALLTYPE GetKeyState(
663 ABI::Windows::System::VirtualKey virtualKey,
664 winui::Core::CoreVirtualKeyStates* KeyState) override {
665 return S_OK;
668 virtual HRESULT STDMETHODCALLTYPE ReleasePointerCapture(void) override {
669 return S_OK;
672 virtual HRESULT STDMETHODCALLTYPE SetPointerCapture(void) override {
673 return S_OK;
676 virtual HRESULT STDMETHODCALLTYPE add_Activated(
677 WindowActivatedHandler* handler,
678 EventRegistrationToken* pCookie) override {
679 window_activated_handler_ = handler;
680 handler->AddRef();
681 return S_OK;
684 virtual HRESULT STDMETHODCALLTYPE remove_Activated(
685 EventRegistrationToken cookie) override {
686 window_activated_handler_->Release();
687 window_activated_handler_ = NULL;
688 return S_OK;
691 virtual HRESULT STDMETHODCALLTYPE add_AutomationProviderRequested(
692 AutomationProviderHandler* handler,
693 EventRegistrationToken* cookie) override {
694 return S_OK;
697 virtual HRESULT STDMETHODCALLTYPE remove_AutomationProviderRequested(
698 EventRegistrationToken cookie) override {
699 return S_OK;
702 virtual HRESULT STDMETHODCALLTYPE add_CharacterReceived(
703 CharEventHandler* handler,
704 EventRegistrationToken* pCookie) override {
705 character_received_handler_ = handler;
706 character_received_handler_->AddRef();
707 return S_OK;
710 virtual HRESULT STDMETHODCALLTYPE remove_CharacterReceived(
711 EventRegistrationToken cookie) override {
712 character_received_handler_->Release();
713 character_received_handler_ = NULL;
714 return S_OK;
717 virtual HRESULT STDMETHODCALLTYPE add_Closed(
718 CoreWindowEventHandler* handler,
719 EventRegistrationToken* pCookie) override {
720 return S_OK;
723 virtual HRESULT STDMETHODCALLTYPE remove_Closed(
724 EventRegistrationToken cookie) override {
725 return S_OK;
728 virtual HRESULT STDMETHODCALLTYPE add_InputEnabled(
729 InputEnabledEventHandler* handler,
730 EventRegistrationToken* pCookie) override {
731 return S_OK;
734 virtual HRESULT STDMETHODCALLTYPE remove_InputEnabled(
735 EventRegistrationToken cookie) override {
736 return S_OK;
739 virtual HRESULT STDMETHODCALLTYPE add_KeyDown(
740 KeyEventHandler* handler,
741 EventRegistrationToken* pCookie) override {
742 key_down_handler_ = handler;
743 key_down_handler_->AddRef();
744 return S_OK;
747 virtual HRESULT STDMETHODCALLTYPE remove_KeyDown(
748 EventRegistrationToken cookie) override {
749 key_down_handler_->Release();
750 key_down_handler_ = NULL;
751 return S_OK;
754 virtual HRESULT STDMETHODCALLTYPE add_KeyUp(
755 KeyEventHandler* handler,
756 EventRegistrationToken* pCookie) override {
757 key_up_handler_ = handler;
758 key_up_handler_->AddRef();
759 return S_OK;
762 virtual HRESULT STDMETHODCALLTYPE remove_KeyUp(
763 EventRegistrationToken cookie) override {
764 key_up_handler_->Release();
765 key_up_handler_ = NULL;
766 return S_OK;
769 virtual HRESULT STDMETHODCALLTYPE add_PointerCaptureLost(
770 PointerEventHandler* handler,
771 EventRegistrationToken* cookie) override {
772 mouse_capture_lost_handler_ = handler;
773 return S_OK;
776 virtual HRESULT STDMETHODCALLTYPE remove_PointerCaptureLost(
777 EventRegistrationToken cookie) override {
778 mouse_capture_lost_handler_ = NULL;
779 return S_OK;
782 virtual HRESULT STDMETHODCALLTYPE add_PointerEntered(
783 PointerEventHandler* handler,
784 EventRegistrationToken* cookie) override {
785 mouse_entered_handler_ = handler;
786 return S_OK;
789 virtual HRESULT STDMETHODCALLTYPE remove_PointerEntered(
790 EventRegistrationToken cookie) override {
791 mouse_entered_handler_ = NULL;
792 return S_OK;
795 virtual HRESULT STDMETHODCALLTYPE add_PointerExited(
796 PointerEventHandler* handler,
797 EventRegistrationToken* cookie) override {
798 mouse_exited_handler_ = handler;
799 return S_OK;
802 virtual HRESULT STDMETHODCALLTYPE remove_PointerExited(
803 EventRegistrationToken cookie) override {
804 mouse_exited_handler_ = NULL;
805 return S_OK;
808 virtual HRESULT STDMETHODCALLTYPE add_PointerMoved(
809 PointerEventHandler* handler,
810 EventRegistrationToken* cookie) override {
811 mouse_moved_handler_ = handler;
812 mouse_moved_handler_->AddRef();
813 return S_OK;
816 virtual HRESULT STDMETHODCALLTYPE remove_PointerMoved(
817 EventRegistrationToken cookie) override {
818 mouse_moved_handler_->Release();
819 mouse_moved_handler_ = NULL;
820 return S_OK;
823 virtual HRESULT STDMETHODCALLTYPE add_PointerPressed(
824 PointerEventHandler* handler,
825 EventRegistrationToken* cookie) override {
826 mouse_pressed_handler_ = handler;
827 mouse_pressed_handler_->AddRef();
828 return S_OK;
831 virtual HRESULT STDMETHODCALLTYPE remove_PointerPressed(
832 EventRegistrationToken cookie) override {
833 mouse_pressed_handler_->Release();
834 mouse_pressed_handler_ = NULL;
835 return S_OK;
838 virtual HRESULT STDMETHODCALLTYPE add_PointerReleased(
839 PointerEventHandler* handler,
840 EventRegistrationToken* cookie) override {
841 mouse_released_handler_ = handler;
842 mouse_released_handler_->AddRef();
843 return S_OK;
846 virtual HRESULT STDMETHODCALLTYPE remove_PointerReleased(
847 EventRegistrationToken cookie) override {
848 mouse_released_handler_->Release();
849 mouse_released_handler_ = NULL;
850 return S_OK;
853 virtual HRESULT STDMETHODCALLTYPE add_TouchHitTesting(
854 TouchHitTestHandler* handler,
855 EventRegistrationToken* pCookie) override {
856 return S_OK;
859 virtual HRESULT STDMETHODCALLTYPE remove_TouchHitTesting(
860 EventRegistrationToken cookie) override {
861 return S_OK;
864 virtual HRESULT STDMETHODCALLTYPE add_PointerWheelChanged(
865 PointerEventHandler* handler,
866 EventRegistrationToken* cookie) override {
867 mouse_wheel_changed_handler_ = handler;
868 mouse_wheel_changed_handler_->AddRef();
869 return S_OK;
872 virtual HRESULT STDMETHODCALLTYPE remove_PointerWheelChanged(
873 EventRegistrationToken cookie) override {
874 mouse_wheel_changed_handler_->Release();
875 mouse_wheel_changed_handler_ = NULL;
876 return S_OK;
879 virtual HRESULT STDMETHODCALLTYPE add_SizeChanged(
880 SizeChangedHandler* handler,
881 EventRegistrationToken* pCookie) override {
882 // TODO(cpu): implement this.
883 return S_OK;
886 virtual HRESULT STDMETHODCALLTYPE remove_SizeChanged(
887 EventRegistrationToken cookie) override {
888 return S_OK;
891 virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
892 VisibilityChangedHandler* handler,
893 EventRegistrationToken* pCookie) override {
894 return S_OK;
897 virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
898 EventRegistrationToken cookie) override {
899 return S_OK;
902 // ICoreWindowInterop implementation:
903 virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) override {
904 if (!core_hwnd_)
905 return E_FAIL;
906 *hwnd = core_hwnd_;
907 return S_OK;
910 virtual HRESULT STDMETHODCALLTYPE put_MessageHandled(
911 boolean value) override {
912 return S_OK;
915 // InputHandler
916 virtual bool HandleKeyboardMessage(const MSG& msg) override {
917 switch (msg.message) {
918 case WM_KEYDOWN:
919 case WM_KEYUP: {
920 mswr::ComPtr<winui::Core::IKeyEventArgs> event_args;
921 event_args = mswr::Make<KeyEvent>(msg);
922 KeyEventHandler* handler = NULL;
923 if (msg.message == WM_KEYDOWN) {
924 handler = key_down_handler_;
925 } else {
926 handler = key_up_handler_;
928 handler->Invoke(this, event_args.Get());
929 break;
932 case WM_CHAR:
933 case WM_DEADCHAR:
934 case WM_UNICHAR: {
935 mswr::ComPtr<winui::Core::ICharacterReceivedEventArgs> event_args;
936 event_args = mswr::Make<KeyEvent>(msg);
937 character_received_handler_->Invoke(this, event_args.Get());
938 break;
941 default:
942 return false;
944 return true;
947 virtual bool HandleMouseMessage(const MSG& msg) override {
948 PointerEventHandler* handler = NULL;
949 mswr::ComPtr<winui::Core::IPointerEventArgs> event_args;
950 event_args = mswr::Make<MouseEvent>(msg);
951 switch (msg.message) {
952 case WM_MOUSEMOVE: {
953 handler = mouse_moved_handler_;
954 break;
956 case WM_LBUTTONDOWN: {
957 case WM_RBUTTONDOWN:
958 case WM_MBUTTONDOWN:
959 handler = mouse_pressed_handler_;
960 break;
963 case WM_LBUTTONUP: {
964 case WM_RBUTTONUP:
965 case WM_MBUTTONUP:
966 handler = mouse_released_handler_;
967 break;
970 case WM_MOUSEWHEEL: {
971 case WM_MOUSEHWHEEL:
972 handler = mouse_wheel_changed_handler_;
973 break;
976 default:
977 return false;
979 DCHECK(handler);
980 handler->Invoke(this, event_args.Get());
981 return true;
984 void OnWindowActivated() {
985 if (window_activated_handler_)
986 window_activated_handler_->Invoke(this, NULL);
989 private:
990 PointerEventHandler* mouse_moved_handler_;
991 PointerEventHandler* mouse_capture_lost_handler_;
992 PointerEventHandler* mouse_pressed_handler_;
993 PointerEventHandler* mouse_released_handler_;
994 PointerEventHandler* mouse_entered_handler_;
995 PointerEventHandler* mouse_exited_handler_;
996 PointerEventHandler* mouse_wheel_changed_handler_;
997 KeyEventHandler* key_down_handler_;
998 KeyEventHandler* key_up_handler_;
999 CharEventHandler* character_received_handler_;
1000 HWND core_hwnd_;
1001 mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher_;
1002 mswr::ComPtr<winapp::Core::IFrameworkView> app_view_;
1003 WindowActivatedHandler* window_activated_handler_;
1006 LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
1007 WPARAM wparam, LPARAM lparam) {
1008 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
1009 tracked_objects::ScopedTracker tracking_profile(
1010 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 MetroDriver WndProc"));
1012 PAINTSTRUCT ps;
1013 HDC hdc;
1014 switch (message) {
1015 case WM_ACTIVATE: {
1016 // HIWORD(wparam) is 1 if the window is minimized.
1017 bool active = (LOWORD(wparam) != WA_INACTIVE) && !HIWORD(wparam);
1018 if (active) {
1019 CoreWindowEmulation* core_window_handler =
1020 reinterpret_cast<CoreWindowEmulation*>(
1021 ::GetProp(hwnd, kAshWin7CoreWindowHandler));
1022 if (core_window_handler)
1023 core_window_handler->OnWindowActivated();
1025 return ::DefWindowProc(hwnd, message, wparam, lparam);
1027 case WM_CREATE:
1028 ++g_window_count;
1029 break;
1030 case WM_PAINT:
1031 hdc = ::BeginPaint(hwnd, &ps);
1032 ::EndPaint(hwnd, &ps);
1033 break;
1034 case WM_CLOSE:
1035 ::DestroyWindow(hwnd);
1036 break;
1037 case WM_DESTROY:
1038 --g_window_count;
1039 if (!g_window_count)
1040 ::PostQuitMessage(0);
1041 break;
1042 // Always allow Chrome to set the cursor.
1043 case WM_SETCURSOR:
1044 return 1;
1045 default:
1046 return ::DefWindowProc(hwnd, message, wparam, lparam);
1048 return 0;
1051 class ActivatedEvent
1052 : public mswr::RuntimeClass<winapp::Activation::IActivatedEventArgs> {
1053 public:
1054 ActivatedEvent(winapp::Activation::ActivationKind activation_kind)
1055 : activation_kind_(activation_kind) {
1058 virtual HRESULT STDMETHODCALLTYPE get_Kind(
1059 winapp::Activation::ActivationKind *value) {
1060 *value = activation_kind_;
1061 return S_OK;
1064 virtual HRESULT STDMETHODCALLTYPE get_PreviousExecutionState(
1065 winapp::Activation::ApplicationExecutionState *value) {
1066 *value = winapp::Activation::ApplicationExecutionState_ClosedByUser;
1067 return S_OK;
1070 virtual HRESULT STDMETHODCALLTYPE get_SplashScreen(
1071 winapp::Activation::ISplashScreen **value) {
1072 return E_FAIL;
1075 private:
1076 winapp::Activation::ActivationKind activation_kind_;
1079 class CoreApplicationViewEmulation
1080 : public mswr::RuntimeClass<winapp::Core::ICoreApplicationView> {
1081 public:
1082 CoreApplicationViewEmulation(winapp::Core::IFrameworkView* app_view) {
1083 core_window_ = mswr::Make<CoreWindowEmulation>(app_view);
1086 HRESULT Activate() {
1087 if (activated_handler_) {
1088 auto ae = mswr::Make<ActivatedEvent>(
1089 winapp::Activation::ActivationKind_File);
1090 return activated_handler_->Invoke(this, ae.Get());
1091 } else {
1092 return S_OK;
1096 HRESULT Close() {
1097 return core_window_->Close();
1100 // ICoreApplicationView implementation:
1101 virtual HRESULT STDMETHODCALLTYPE get_CoreWindow(
1102 winui::Core::ICoreWindow** value) {
1103 if (!core_window_)
1104 return E_FAIL;
1105 return core_window_.CopyTo(value);
1108 virtual HRESULT STDMETHODCALLTYPE add_Activated(
1109 ActivatedHandler* handler,
1110 EventRegistrationToken* token) {
1111 // The real component supports multiple handles but we don't yet.
1112 if (activated_handler_)
1113 return E_FAIL;
1114 activated_handler_ = handler;
1115 return S_OK;
1118 virtual HRESULT STDMETHODCALLTYPE remove_Activated(
1119 EventRegistrationToken token) {
1120 // Chrome never unregisters handlers, so we don't care about it.
1121 return S_OK;
1124 virtual HRESULT STDMETHODCALLTYPE get_IsMain(
1125 boolean* value) {
1126 return S_OK;
1129 virtual HRESULT STDMETHODCALLTYPE get_IsHosted(
1130 boolean* value) {
1131 return S_OK;
1134 private:
1135 mswr::ComPtr<CoreWindowEmulation> core_window_;
1136 mswr::ComPtr<ActivatedHandler> activated_handler_;
1139 class CoreApplicationWin7Emulation
1140 : public mswr::RuntimeClass<winapp::Core::ICoreApplication,
1141 winapp::Core::ICoreApplicationExit> {
1142 public:
1143 // ICoreApplication implementation:
1145 virtual HRESULT STDMETHODCALLTYPE get_Id(
1146 HSTRING* value) {
1147 return S_OK;
1150 virtual HRESULT STDMETHODCALLTYPE add_Suspending(
1151 winfoundtn::IEventHandler<winapp::SuspendingEventArgs*>* handler,
1152 EventRegistrationToken* token) {
1153 return S_OK;
1156 virtual HRESULT STDMETHODCALLTYPE remove_Suspending(
1157 EventRegistrationToken token) {
1158 return S_OK;
1161 virtual HRESULT STDMETHODCALLTYPE add_Resuming(
1162 winfoundtn::IEventHandler<IInspectable*>* handler,
1163 EventRegistrationToken* token) {
1164 return S_OK;
1167 virtual HRESULT STDMETHODCALLTYPE remove_Resuming(
1168 EventRegistrationToken token) {
1169 return S_OK;
1172 virtual HRESULT STDMETHODCALLTYPE get_Properties(
1173 winfoundtn::Collections::IPropertySet** value) {
1174 return S_OK;
1177 virtual HRESULT STDMETHODCALLTYPE GetCurrentView(
1178 winapp::Core::ICoreApplicationView** value) {
1179 return S_OK;
1182 virtual HRESULT STDMETHODCALLTYPE Run(
1183 winapp::Core::IFrameworkViewSource* viewSource) {
1184 HRESULT hr = viewSource->CreateView(app_view_.GetAddressOf());
1185 if (FAILED(hr))
1186 return hr;
1187 view_emulation_ = mswr::Make<CoreApplicationViewEmulation>(
1188 app_view_.Get());
1189 hr = app_view_->Initialize(view_emulation_.Get());
1190 if (FAILED(hr))
1191 return hr;
1192 mswr::ComPtr<winui::Core::ICoreWindow> core_window;
1193 hr = view_emulation_->get_CoreWindow(core_window.GetAddressOf());
1194 if (FAILED(hr))
1195 return hr;
1196 hr = app_view_->SetWindow(core_window.Get());
1197 if (FAILED(hr))
1198 return hr;
1199 hr = app_view_->Load(NULL);
1200 if (FAILED(hr))
1201 return hr;
1202 hr = view_emulation_->Activate();
1203 if (FAILED(hr))
1204 return hr;
1205 return app_view_->Run();
1208 virtual HRESULT STDMETHODCALLTYPE RunWithActivationFactories(
1209 winfoundtn::IGetActivationFactory* activationFactoryCallback) {
1210 return S_OK;
1213 // ICoreApplicationExit implementation:
1215 virtual HRESULT STDMETHODCALLTYPE Exit(void) {
1216 return view_emulation_->Close();
1219 virtual HRESULT STDMETHODCALLTYPE add_Exiting(
1220 winfoundtn::IEventHandler<IInspectable*>* handler,
1221 EventRegistrationToken* token) {
1222 return S_OK;
1225 virtual HRESULT STDMETHODCALLTYPE remove_Exiting(
1226 EventRegistrationToken token) {
1227 return S_OK;
1230 private:
1231 mswr::ComPtr<winapp::Core::IFrameworkView> app_view_;
1232 mswr::ComPtr<CoreApplicationViewEmulation> view_emulation_;
1236 mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows7() {
1237 HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1238 if (FAILED(hr))
1239 CHECK(false);
1240 return mswr::Make<CoreApplicationWin7Emulation>();