diff options
author | scottmg <scottmg@chromium.org> | 2016-03-18 14:54:25 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-18 21:56:12 +0000 |
commit | eff89b21d516cc5f9ec85ce455eeaf5f3a1817b7 (patch) | |
tree | 1b2b0f20286ff21a9439bda60f7b703da420ac5e /win8 | |
parent | 10c89129c2fc6f763d011e50599f0dd6795b72cb (diff) | |
download | chromium_src-eff89b21d516cc5f9ec85ce455eeaf5f3a1817b7.zip chromium_src-eff89b21d516cc5f9ec85ce455eeaf5f3a1817b7.tar.gz chromium_src-eff89b21d516cc5f9ec85ce455eeaf5f3a1817b7.tar.bz2 |
Remove win8/metro_driver
Dead code now.
R=ananta@chromium.org
BUG=558054
Review URL: https://codereview.chromium.org/1815463002
Cr-Commit-Position: refs/heads/master@{#382101}
Diffstat (limited to 'win8')
48 files changed, 0 insertions, 7327 deletions
diff --git a/win8/metro_driver/BUILD.gn b/win8/metro_driver/BUILD.gn deleted file mode 100644 index 346b631..0000000 --- a/win8/metro_driver/BUILD.gn +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2015 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. - -import("//build/config/ui.gni") -import("//chrome/version.gni") -import("//testing/test.gni") - -shared_library("metro_driver") { - sources = [ - "display_properties.cc", - "display_properties.h", - "stdafx.h", - "winrt_utils.cc", - "winrt_utils.h", - ] - - deps = [ - ":version_resources", - "//base", - "//chrome/common:constants", - "//chrome/installer/util:with_no_strings", - "//crypto", - "//ipc", - "//sandbox", - "//ui/events", - "//ui/gfx", - "//ui/gfx/geometry", - "//ui/metro_viewer", - "//url", - ] - - if (use_aura) { - sources += [ - "direct3d_helper.cc", - "direct3d_helper.h", - ] - - deps += [ - "//ui/events:gesture_detection", - "//win8/metro_driver/ime", - ] - } else { - sources = [ - "chrome_app_view.cc", - "chrome_app_view.h", - "chrome_url_launch_handler.cc", - "chrome_url_launch_handler.h", - "devices_handler.cc", - "devices_handler.h", - "metro_dialog_box.cc", - "metro_dialog_box.h", - "print_document_source.cc", - "print_document_source.h", - "print_handler.cc", - "print_handler.h", - "secondary_tile.cc", - "secondary_tile.h", - "settings_handler.cc", - "settings_handler.h", - "toast_notification_handler.cc", - "toast_notification_handler.h", - ] - } - - libs = [ - "D2D1.lib", - "D3D11.lib", - "runtimeobject.lib", - ] - - ldflags = [ - "/DELAYLOAD:API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL", - "/DELAYLOAD:API-MS-WIN-CORE-WINRT-L1-1-0.DLL", - "/DELAYLOAD:API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL", - ] -} - -process_version("version_resources") { - visibility = [ ":*" ] - sources = [ - "metro_driver_dll.ver", - ] - output = "$target_gen_dir/metro_driver_dll_version.rc" - template_file = chrome_version_rc_template -} - -test("metro_driver_unittests") { - sources = [ - "run_all_unittests.cc", - "winrt_utils.cc", - "winrt_utils.h", - "winrt_utils_unittest.cc", - ] - - deps = [ - ":metro_driver", - "//base", - "//chrome/installer/util:with_rc_strings", - "//testing/gtest", - ] -} diff --git a/win8/metro_driver/DEPS b/win8/metro_driver/DEPS deleted file mode 100644 index c767809..0000000 --- a/win8/metro_driver/DEPS +++ /dev/null @@ -1,5 +0,0 @@ -include_rules = [ - # Allow metro_driver to include from delegate_execute *temporarily*. - # TODO(ananta): Remove this by fixing toast_notification_handler.cc. - "+win8/delegate_execute", -]
\ No newline at end of file diff --git a/win8/metro_driver/OWNERS b/win8/metro_driver/OWNERS deleted file mode 100644 index 3802937..0000000 --- a/win8/metro_driver/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ -ananta@chromium.org -cpu@chromium.org -grt@chromium.org -mad@chromium.org -robertshield@chromium.org
\ No newline at end of file diff --git a/win8/metro_driver/chrome_app_view.cc b/win8/metro_driver/chrome_app_view.cc deleted file mode 100644 index 051f37f..0000000 --- a/win8/metro_driver/chrome_app_view.cc +++ /dev/null @@ -1,1216 +0,0 @@ -// 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.h" - -#include <corewindow.h> -#include <windows.applicationModel.datatransfer.h> -#include <windows.foundation.h> - -#include <algorithm> - -#include "base/bind.h" -#include "base/message_loop/message_loop.h" -#include "base/win/metro.h" -// This include allows to send WM_SYSCOMMANDs to chrome. -#include "chrome/app/chrome_command_ids.h" -#include "ui/base/ui_base_switches.h" -#include "ui/gfx/native_widget_types.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::WindowSizeChangedEventArgs*> SizeChangedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Input::EdgeGesture*, - winui::Input::EdgeGestureEventArgs*> EdgeEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winapp::DataTransfer::DataTransferManager*, - winapp::DataTransfer::DataRequestedEventArgs*> ShareDataRequestedHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::ViewManagement::InputPane*, - winui::ViewManagement::InputPaneVisibilityEventArgs*> - InputPaneEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::PointerEventArgs*> PointerEventHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Core::CoreWindow*, - winui::Core::KeyEventArgs*> KeyEventHandler; - -struct Globals globals; - -// TODO(ananta) -// Remove this once we consolidate metro driver with chrome. -const wchar_t kMetroGetCurrentTabInfoMessage[] = - L"CHROME_METRO_GET_CURRENT_TAB_INFO"; - -static const int kFlipWindowsHotKeyId = 0x0000baba; - -static const int kAnimateWindowTimeoutMs = 200; - -static const int kCheckOSKDelayMs = 300; - -const wchar_t kOSKClassName[] = L"IPTip_Main_Window"; - -static const int kOSKAdjustmentOffset = 20; - -const wchar_t kChromeSubclassWindowProp[] = L"MetroChromeWindowProc"; - -namespace { - -enum Modifier { - NONE, - SHIFT = 1, - CONTROL = 2, - ALT = 4 -}; - -// Helper function to send keystrokes via the SendInput function. -// Params: -// mnemonic_char: The keystroke to be sent. -// modifiers: Combination with Alt, Ctrl, Shift, etc. -// extended: whether this is an extended key. -// unicode: whether this is a unicode key. -void SendMnemonic(WORD mnemonic_char, Modifier modifiers, bool extended, - bool unicode) { - INPUT keys[4] = {0}; // Keyboard events - int key_count = 0; // Number of generated events - - if (modifiers & SHIFT) { - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = VK_SHIFT; - keys[key_count].ki.wScan = MapVirtualKey(VK_SHIFT, 0); - key_count++; - } - - if (modifiers & CONTROL) { - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = VK_CONTROL; - keys[key_count].ki.wScan = MapVirtualKey(VK_CONTROL, 0); - key_count++; - } - - if (modifiers & ALT) { - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = VK_MENU; - keys[key_count].ki.wScan = MapVirtualKey(VK_MENU, 0); - key_count++; - } - - keys[key_count].type = INPUT_KEYBOARD; - keys[key_count].ki.wVk = mnemonic_char; - keys[key_count].ki.wScan = MapVirtualKey(mnemonic_char, 0); - - if (extended) - keys[key_count].ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; - if (unicode) - keys[key_count].ki.dwFlags |= KEYEVENTF_UNICODE; - key_count++; - - bool should_sleep = key_count > 1; - - // Send key downs - for (int i = 0; i < key_count; i++) { - SendInput(1, &keys[ i ], sizeof(keys[0])); - keys[i].ki.dwFlags |= KEYEVENTF_KEYUP; - if (should_sleep) { - Sleep(10); - } - } - - // Now send key ups in reverse order - for (int i = key_count; i; i--) { - SendInput(1, &keys[ i - 1 ], sizeof(keys[0])); - if (should_sleep) { - Sleep(10); - } - } -} - -// Helper function to Exit metro chrome cleanly. If we are in the foreground -// then we try and exit by sending an Alt+F4 key combination to the core -// window which ensures that the chrome application tile does not show up in -// the running metro apps list on the top left corner. We have seen cases -// where this does work. To workaround that we invoke the -// ICoreApplicationExit::Exit function in a background delayed task which -// ensures that chrome exits. -void MetroExit(bool send_alt_f4_mnemonic) { - if (send_alt_f4_mnemonic && globals.view && - globals.view->core_window_hwnd() == ::GetForegroundWindow()) { - DVLOG(1) << "We are in the foreground. Exiting via Alt F4"; - SendMnemonic(VK_F4, ALT, false, false); - DWORD core_window_process_id = 0; - DWORD core_window_thread_id = GetWindowThreadProcessId( - globals.view->core_window_hwnd(), &core_window_process_id); - if (core_window_thread_id != ::GetCurrentThreadId()) { - globals.appview_task_runner->PostDelayedTask( - FROM_HERE, - base::Bind(&MetroExit, false), - base::TimeDelta::FromMilliseconds(100)); - } - } else { - globals.app_exit->Exit(); - } -} - -void AdjustToFitWindow(HWND hwnd, int flags) { - RECT rect = {0}; - ::GetWindowRect(globals.view->core_window_hwnd() , &rect); - int cx = rect.right - rect.left; - int cy = rect.bottom - rect.top; - - ::SetWindowPos(hwnd, HWND_TOP, - rect.left, rect.top, cx, cy, - SWP_NOZORDER | flags); -} - -LRESULT CALLBACK ChromeWindowProc(HWND window, - UINT message, - WPARAM wp, - LPARAM lp) { - if (message == WM_SETCURSOR) { - // Override the WM_SETCURSOR message to avoid showing the resize cursor - // as the mouse moves to the edge of the screen. - switch (LOWORD(lp)) { - case HTBOTTOM: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: - case HTLEFT: - case HTRIGHT: - case HTTOP: - case HTTOPLEFT: - case HTTOPRIGHT: - lp = MAKELPARAM(HTCLIENT, HIWORD(lp)); - break; - default: - break; - } - } - - WNDPROC old_proc = reinterpret_cast<WNDPROC>( - ::GetProp(window, kChromeSubclassWindowProp)); - DCHECK(old_proc); - return CallWindowProc(old_proc, window, message, wp, lp); -} - -void AdjustFrameWindowStyleForMetro(HWND hwnd) { - DVLOG(1) << __FUNCTION__; - // Ajust the frame so the live preview works and the frame buttons dissapear. - ::SetWindowLong(hwnd, GWL_STYLE, - WS_POPUP | (::GetWindowLong(hwnd, GWL_STYLE) & - ~(WS_MAXIMIZE | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU))); - ::SetWindowLong(hwnd, GWL_EXSTYLE, - ::GetWindowLong(hwnd, GWL_EXSTYLE) & ~(WS_EX_DLGMODALFRAME | - WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); - - // Subclass the wndproc of the frame window, if it's not already there. - if (::GetProp(hwnd, kChromeSubclassWindowProp) == NULL) { - WNDPROC old_chrome_proc = - reinterpret_cast<WNDPROC>(::SetWindowLongPtr( - hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(ChromeWindowProc))); - ::SetProp(hwnd, kChromeSubclassWindowProp, old_chrome_proc); - } - AdjustToFitWindow(hwnd, SWP_FRAMECHANGED | SWP_NOACTIVATE); -} - -void SetFrameWindowInternal(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - - HWND current_top_frame = - !globals.host_windows.empty() ? globals.host_windows.front().first : NULL; - if (hwnd != current_top_frame && IsWindow(current_top_frame)) { - DVLOG(1) << "Hiding current top window, hwnd=" - << LONG_PTR(current_top_frame); - ::ShowWindow(current_top_frame, SW_HIDE); - } - - // Visible frame windows always need to be at the head of the list. - // Check if the window being shown already exists in our global list. - // If no then add it at the head of the list. - // If yes, retrieve the osk window scrolled state, remove the window from the - // list and readd it at the head. - std::list<std::pair<HWND, bool> >::iterator index = - std::find_if(globals.host_windows.begin(), globals.host_windows.end(), - [hwnd](std::pair<HWND, bool>& item) { - return (item.first == hwnd); - }); - - bool window_scrolled_state = false; - bool new_window = (index == globals.host_windows.end()); - if (!new_window) { - window_scrolled_state = index->second; - globals.host_windows.erase(index); - } - - globals.host_windows.push_front(std::make_pair(hwnd, window_scrolled_state)); - - if (new_window) { - AdjustFrameWindowStyleForMetro(hwnd); - } else { - DVLOG(1) << "Adjusting new top window to core window size"; - AdjustToFitWindow(hwnd, 0); - } - if (globals.view->GetViewState() == - winui::ViewManagement::ApplicationViewState_Snapped) { - DVLOG(1) << "Enabling Metro snap state on new window: " << hwnd; - ::PostMessageW(hwnd, WM_SYSCOMMAND, IDC_METRO_SNAP_ENABLE, 0); - } -} - -void CloseFrameWindowInternal(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - - globals.host_windows.remove_if([hwnd](std::pair<HWND, bool>& item) { - return (item.first == hwnd); - }); - - if (globals.host_windows.size() > 0) { - DVLOG(1) << "Making new top frame window visible:" - << reinterpret_cast<int>(globals.host_windows.front().first); - AdjustToFitWindow(globals.host_windows.front().first, SWP_SHOWWINDOW); - } else { - // time to quit - DVLOG(1) << "Last host window closed. Calling Exit()."; - MetroExit(true); - } -} - -void FlipFrameWindowsInternal() { - DVLOG(1) << __FUNCTION__; - // Get the first window in the frame windows queue and push it to the end. - // Metroize the next window in the queue. - if (globals.host_windows.size() > 1) { - std::pair<HWND, bool> current_top_window = globals.host_windows.front(); - globals.host_windows.pop_front(); - - DVLOG(1) << "Making new top frame window visible:" - << reinterpret_cast<int>(globals.host_windows.front().first); - - AdjustToFitWindow(globals.host_windows.front().first, SWP_SHOWWINDOW); - - DVLOG(1) << "Hiding current top window:" - << reinterpret_cast<int>(current_top_window.first); - AnimateWindow(current_top_window.first, kAnimateWindowTimeoutMs, - AW_HIDE | AW_HOR_POSITIVE | AW_SLIDE); - - globals.host_windows.push_back(current_top_window); - } -} - -} // namespace - -void ChromeAppView::DisplayNotification( - const ToastNotificationHandler::DesktopNotification& notification) { - DVLOG(1) << __FUNCTION__; - - if (IsValidNotification(notification.id)) { - NOTREACHED() << "Duplicate notification id passed in."; - return; - } - - base::AutoLock lock(notification_lock_); - - ToastNotificationHandler* notification_handler = - new ToastNotificationHandler; - - notification_map_[notification.id].reset(notification_handler); - notification_handler->DisplayNotification(notification); -} - -void ChromeAppView::CancelNotification(const std::string& notification) { - DVLOG(1) << __FUNCTION__; - - base::AutoLock lock(notification_lock_); - - NotificationMap::iterator index = notification_map_.find(notification); - if (index == notification_map_.end()) { - NOTREACHED() << "Invalid notification:" << notification.c_str(); - return; - } - - scoped_ptr<ToastNotificationHandler> notification_handler( - index->second.release()); - - notification_map_.erase(index); - - notification_handler->CancelNotification(); -} - -// Returns true if the notification passed in is valid. -bool ChromeAppView::IsValidNotification(const std::string& notification) { - DVLOG(1) << __FUNCTION__; - - base::AutoLock lock(notification_lock_); - return notification_map_.find(notification) != notification_map_.end(); -} - -void ChromeAppView::ShowDialogBox( - const MetroDialogBox::DialogBoxInfo& dialog_box_info) { - VLOG(1) << __FUNCTION__; - dialog_box_.Show(dialog_box_info); -} - -void ChromeAppView::DismissDialogBox() { - VLOG(1) << __FUNCTION__; - dialog_box_.Dismiss(); -} - -// static -HRESULT ChromeAppView::Unsnap() { - mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> view_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ViewManagement_ApplicationView, - view_statics.GetAddressOf()); - CheckHR(hr); - - winui::ViewManagement::ApplicationViewState state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - hr = view_statics->get_Value(&state); - CheckHR(hr); - - if (state == winui::ViewManagement::ApplicationViewState_Snapped) { - boolean success = FALSE; - hr = view_statics->TryUnsnap(&success); - - if (FAILED(hr) || !success) { - LOG(ERROR) << "Failed to unsnap. Error 0x" << hr; - if (SUCCEEDED(hr)) - hr = E_UNEXPECTED; - } - } - return hr; -} - -void ChromeAppView::SetFullscreen(bool fullscreen) { - VLOG(1) << __FUNCTION__; - - if (osk_offset_adjustment_) { - VLOG(1) << "Scrolling the window down by: " - << osk_offset_adjustment_; - - ::ScrollWindowEx(globals.host_windows.front().first, - 0, - osk_offset_adjustment_, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE | SW_SCROLLCHILDREN); - osk_offset_adjustment_ = 0; - } -} - -winui::ViewManagement::ApplicationViewState ChromeAppView::GetViewState() { - winui::ViewManagement::ApplicationViewState view_state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - app_view_->get_Value(&view_state); - return view_state; -} - -void UnsnapHelper() { - ChromeAppView::Unsnap(); -} - -extern "C" __declspec(dllexport) -void MetroUnsnap() { - DVLOG(1) << __FUNCTION__; - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind(&UnsnapHelper)); -} - -extern "C" __declspec(dllexport) -HWND GetRootWindow() { - DVLOG(1) << __FUNCTION__; - return globals.view->core_window_hwnd(); -} - -extern "C" __declspec(dllexport) -void SetFrameWindow(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind(&SetFrameWindowInternal, hwnd)); -} - -// TODO(ananta) -// Handle frame window close by deleting it from the window list and making the -// next guy visible. -extern "C" __declspec(dllexport) - void CloseFrameWindow(HWND hwnd) { - DVLOG(1) << __FUNCTION__ << ", hwnd=" << LONG_PTR(hwnd); - - // This is a hack to ensure that the BrowserViewLayout code layout happens - // just at the right time to hide the switcher button if it is visible. - globals.appview_task_runner->PostDelayedTask( - FROM_HERE, base::Bind(&CloseFrameWindowInternal, hwnd), - base::TimeDelta::FromMilliseconds(50)); -} - -// Returns the initial url. This returns a valid url only if we were launched -// into metro via a url navigation. -extern "C" __declspec(dllexport) -const wchar_t* GetInitialUrl() { - DVLOG(1) << __FUNCTION__; - bool was_initial_activation = globals.is_initial_activation; - globals.is_initial_activation = false; - if (!was_initial_activation || globals.navigation_url.empty()) - return L""; - - const wchar_t* initial_url = globals.navigation_url.c_str(); - DVLOG(1) << initial_url; - return initial_url; -} - -// Returns the initial search string. This returns a valid url only if we were -// launched into metro via the search charm -extern "C" __declspec(dllexport) -const wchar_t* GetInitialSearchString() { - DVLOG(1) << __FUNCTION__; - bool was_initial_activation = globals.is_initial_activation; - globals.is_initial_activation = false; - if (!was_initial_activation || globals.search_string.empty()) - return L""; - - const wchar_t* initial_search_string = globals.search_string.c_str(); - DVLOG(1) << initial_search_string; - return initial_search_string; -} - -// Returns the launch type. -extern "C" __declspec(dllexport) -base::win::MetroLaunchType GetLaunchType( - base::win::MetroPreviousExecutionState* previous_state) { - if (previous_state) { - *previous_state = static_cast<base::win::MetroPreviousExecutionState>( - globals.previous_state); - } - return static_cast<base::win::MetroLaunchType>( - globals.initial_activation_kind); -} - -extern "C" __declspec(dllexport) -void FlipFrameWindows() { - DVLOG(1) << __FUNCTION__; - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind(&FlipFrameWindowsInternal)); -} - -extern "C" __declspec(dllexport) -void DisplayNotification(const char* origin_url, const char* icon_url, - const wchar_t* title, const wchar_t* body, - const wchar_t* display_source, - const char* notification_id, - base::win::MetroNotificationClickedHandler handler, - const wchar_t* handler_context) { - // TODO(ananta) - // Needs implementation. - DVLOG(1) << __FUNCTION__; - - ToastNotificationHandler::DesktopNotification notification(origin_url, - icon_url, - title, - body, - display_source, - notification_id, - handler, - handler_context); - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind(&ChromeAppView::DisplayNotification, - globals.view, notification)); -} - -extern "C" __declspec(dllexport) -bool CancelNotification(const char* notification_id) { - // TODO(ananta) - // Needs implementation. - DVLOG(1) << __FUNCTION__; - - if (!globals.view->IsValidNotification(notification_id)) { - NOTREACHED() << "Invalid notification id :" << notification_id; - return false; - } - - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind(&ChromeAppView::CancelNotification, - globals.view, std::string(notification_id))); - return true; -} - -// Returns command line switches if any to be used by metro chrome. -extern "C" __declspec(dllexport) -const wchar_t* GetMetroCommandLineSwitches() { - DVLOG(1) << __FUNCTION__; - // The metro_command_line_switches field should be filled up once. - // ideally in ChromeAppView::Activate. - return globals.metro_command_line_switches.c_str(); -} - -// Provides functionality to display a metro style dialog box with two buttons. -// Only one dialog box can be displayed at any given time. -extern "C" __declspec(dllexport) -void ShowDialogBox( - const wchar_t* title, - const wchar_t* content, - const wchar_t* button1_label, - const wchar_t* button2_label, - base::win::MetroDialogButtonPressedHandler button1_handler, - base::win::MetroDialogButtonPressedHandler button2_handler) { - VLOG(1) << __FUNCTION__; - - DCHECK(title); - DCHECK(content); - DCHECK(button1_label); - DCHECK(button2_label); - DCHECK(button1_handler); - DCHECK(button2_handler); - - MetroDialogBox::DialogBoxInfo dialog_box_info; - dialog_box_info.title = title; - dialog_box_info.content = content; - dialog_box_info.button1_label = button1_label; - dialog_box_info.button2_label = button2_label; - dialog_box_info.button1_handler = button1_handler; - dialog_box_info.button2_handler = button2_handler; - - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind( - &ChromeAppView::ShowDialogBox, globals.view, dialog_box_info)); -} - -// Provides functionality to dismiss the previously displayed metro style -// dialog box. -extern "C" __declspec(dllexport) -void DismissDialogBox() { - VLOG(1) << __FUNCTION__; - - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind( - &ChromeAppView::DismissDialogBox, - globals.view)); -} - -extern "C" __declspec(dllexport) -void SetFullscreen(bool fullscreen) { - VLOG(1) << __FUNCTION__; - - globals.appview_task_runner->PostTask( - FROM_HERE, base::Bind( - &ChromeAppView::SetFullscreen, - globals.view, fullscreen)); -} - -template <typename ContainerT> -void CloseSecondaryWindows(ContainerT& windows) { - DVLOG(1) << "Closing secondary windows", windows.size(); - std::for_each(windows.begin(), windows.end(), [](HWND hwnd) { - ::PostMessageW(hwnd, WM_CLOSE, 0, 0); - }); - windows.clear(); -} - -void EndChromeSession() { - DVLOG(1) << "Sending chrome WM_ENDSESSION window message."; - ::SendMessage(globals.host_windows.front().first, WM_ENDSESSION, FALSE, - ENDSESSION_CLOSEAPP); -} - -DWORD WINAPI HostMainThreadProc(void*) { - // Test feature - devs have requested the ability to easily add metro-chrome - // command line arguments. This is hard since shortcut arguments are ignored, - // by Metro, so we instead read them directly from the pinned taskbar - // shortcut. This may call Coinitialize and there is tell of badness - // occurring if CoInitialize is called on a metro thread. - globals.metro_command_line_switches = - winrt_utils::ReadArgumentsFromPinnedTaskbarShortcut(); - - globals.g_core_proc = - reinterpret_cast<WNDPROC>(::SetWindowLongPtr( - globals.view->core_window_hwnd(), GWLP_WNDPROC, - reinterpret_cast<LONG_PTR>(ChromeAppView::CoreWindowProc))); - DWORD exit_code = globals.host_main(globals.host_context); - - DVLOG(1) << "host thread done, exit_code=" << exit_code; - MetroExit(true); - return exit_code; -} - -ChromeAppView::ChromeAppView() - : osk_visible_notification_received_(false), - osk_offset_adjustment_(0), - core_window_hwnd_(NULL) { - globals.previous_state = - winapp::Activation::ApplicationExecutionState_NotRunning; -} - -ChromeAppView::~ChromeAppView() { - DVLOG(1) << __FUNCTION__; -} - -IFACEMETHODIMP -ChromeAppView::Initialize(winapp::Core::ICoreApplicationView* view) { - view_ = view; - DVLOG(1) << __FUNCTION__; - - HRESULT hr = view_->add_Activated(mswr::Callback<ActivatedHandler>( - this, &ChromeAppView::OnActivate).Get(), - &activated_token_); - CheckHR(hr); - return hr; -} - -IFACEMETHODIMP -ChromeAppView::SetWindow(winui::Core::ICoreWindow* window) { - window_ = window; - DVLOG(1) << __FUNCTION__; - - // Retrieve the native window handle via the interop layer. - mswr::ComPtr<ICoreWindowInterop> interop; - HRESULT hr = window->QueryInterface(interop.GetAddressOf()); - CheckHR(hr); - hr = interop->get_WindowHandle(&core_window_hwnd_); - CheckHR(hr); - - hr = url_launch_handler_.Initialize(); - CheckHR(hr, "Failed to initialize url launch handler."); - // Register for size notifications. - hr = window_->add_SizeChanged(mswr::Callback<SizeChangedHandler>( - this, &ChromeAppView::OnSizeChanged).Get(), - &sizechange_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, "Failed to activate IEdgeGestureStatics."); - - 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, &ChromeAppView::OnEdgeGestureCompleted).Get(), - &edgeevent_token_); - CheckHR(hr); - - // Register for share notifications. - mswr::ComPtr<winapp::DataTransfer::IDataTransferManagerStatics> - data_mgr_statics; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_ApplicationModel_DataTransfer_DataTransferManager, - data_mgr_statics.GetAddressOf()); - CheckHR(hr, "Failed to activate IDataTransferManagerStatics."); - - mswr::ComPtr<winapp::DataTransfer::IDataTransferManager> data_transfer_mgr; - hr = data_mgr_statics->GetForCurrentView(&data_transfer_mgr); - CheckHR(hr, "Failed to get IDataTransferManager for current view."); - - hr = data_transfer_mgr->add_DataRequested( - mswr::Callback<ShareDataRequestedHandler>( - this, &ChromeAppView::OnShareDataRequested).Get(), - &share_data_requested_token_); - CheckHR(hr); - - // TODO(ananta) - // 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()); - CheckHR(hr); - - DVLOG(1) << "Created appview instance."; - - hr = devices_handler_.Initialize(window); - // Don't check or return the failure here, we need to let the app - // 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."; - return S_OK; -} - -IFACEMETHODIMP -ChromeAppView::Load(HSTRING entryPoint) { - DVLOG(1) << __FUNCTION__; - return S_OK; -} - -void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) { - // We're entering a nested message loop, let's allow dispatching - // tasks while we're in there. - base::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. - base::MessageLoop::current()->QuitWhenIdle(); -} - -void ChromeAppView::CheckForOSKActivation() { - // Hack for checking if the OSK was displayed while we are in the foreground. - // The input pane notifications which are supposed to fire when the OSK is - // shown and hidden don't seem to be firing in Windows 8 metro for us. - // The current hack is supposed to workaround that issue till we figure it - // out. Logic is to find the OSK window and see if we are the foreground - // process. If yes then fire the notification once for when the OSK is shown - // and once for when it is hidden. - // TODO(ananta) - // Take this out when the documented input pane notification issues are - // addressed. - HWND osk = ::FindWindow(kOSKClassName, NULL); - if (::IsWindow(osk)) { - HWND foreground_window = ::GetForegroundWindow(); - if (globals.host_windows.size() > 0 && - foreground_window == globals.host_windows.front().first) { - RECT osk_rect = {0}; - ::GetWindowRect(osk, &osk_rect); - - if (::IsWindowVisible(osk) && ::IsWindowEnabled(osk)) { - if (!globals.view->osk_visible_notification_received()) { - DVLOG(1) << "Found KB window while we are in the forground."; - HandleInputPaneVisible(osk_rect); - } - } else if (osk_visible_notification_received()) { - DVLOG(1) << "KB window hidden while we are in the foreground."; - HandleInputPaneHidden(osk_rect); - } - } - } - base::MessageLoop::current()->PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeAppView::CheckForOSKActivation, base::Unretained(this)), - base::TimeDelta::FromMilliseconds(kCheckOSKDelayMs)); -} - -IFACEMETHODIMP -ChromeAppView::Run() { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<winui::Core::ICoreDispatcher> 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. - base::MessageLoopForUI msg_loop; - - // Announce our message loop task runner to the world. - globals.appview_task_runner = msg_loop.task_runner(); - - // And post the task that'll do the inner Metro message pumping to it. - msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); - - // Post the recurring task which checks for OSK activation in metro chrome. - // Please refer to the comments in the CheckForOSKActivation function for why - // this is needed. - // TODO(ananta) - // Take this out when the documented OSK notifications start working. - msg_loop.PostDelayedTask( - FROM_HERE, - base::Bind(&ChromeAppView::CheckForOSKActivation, - base::Unretained(this)), - base::TimeDelta::FromMilliseconds(kCheckOSKDelayMs)); - - msg_loop.Run(); - - globals.appview_task_runner = NULL; - - DVLOG(0) << "ProcessEvents done, hr=" << hr; - - // We join here with chrome's main thread so that the chrome is not killed - // while a critical operation is still in progress. Now, if there are host - // windows active it is possible we end up stuck on the wait below therefore - // we tell chrome to close its windows. - if (!globals.host_windows.empty()) { - DVLOG(1) << "Chrome still has windows open!"; - EndChromeSession(); - } - DWORD wr = ::WaitForSingleObject(globals.host_thread, INFINITE); - if (wr != WAIT_OBJECT_0) { - DVLOG(1) << "Waiting for host thread failed : " << wr; - } - - DVLOG(1) << "Host thread exited"; - - ::CloseHandle(globals.host_thread); - globals.host_thread = NULL; - return hr; -} - -IFACEMETHODIMP -ChromeAppView::Uninitialize() { - DVLOG(1) << __FUNCTION__; - window_ = nullptr; - view_ = nullptr; - base::AutoLock lock(notification_lock_); - notification_map_.clear(); - return S_OK; -} - -HRESULT ChromeAppView::RegisterInputPaneNotifications() { - DVLOG(1) << __FUNCTION__; - - mswr::ComPtr<winui::ViewManagement::IInputPaneStatics> - input_pane_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ViewManagement_InputPane, - input_pane_statics.GetAddressOf()); - CheckHR(hr); - - hr = input_pane_statics->GetForCurrentView(&input_pane_); - CheckHR(hr); - DVLOG(1) << "Got input pane."; - - hr = input_pane_->add_Showing( - mswr::Callback<InputPaneEventHandler>( - this, &ChromeAppView::OnInputPaneVisible).Get(), - &input_pane_visible_token_); - CheckHR(hr); - - DVLOG(1) << "Added showing event handler for input pane", - input_pane_visible_token_.value; - - hr = input_pane_->add_Hiding( - mswr::Callback<InputPaneEventHandler>( - this, &ChromeAppView::OnInputPaneHiding).Get(), - &input_pane_hiding_token_); - CheckHR(hr); - - DVLOG(1) << "Added hiding event handler for input pane, value=" - << input_pane_hiding_token_.value; - return hr; -} - -HRESULT ChromeAppView::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(); - url_launch_handler_.Activate(args); - - if (globals.previous_state == - winapp::Activation::ApplicationExecutionState_Running && - globals.host_thread) { - DVLOG(1) << "Already running. Skipping rest of OnActivate."; - return S_OK; - } - - if (!globals.host_thread) { - DWORD chrome_ui_thread_id = 0; - globals.host_thread = - ::CreateThread(NULL, 0, HostMainThreadProc, NULL, 0, - &chrome_ui_thread_id); - - if (!globals.host_thread) { - NOTREACHED() << "thread creation failed."; - return E_UNEXPECTED; - } - } - - if (RegisterHotKey(core_window_hwnd_, kFlipWindowsHotKeyId, - MOD_CONTROL, VK_F12)) { - DVLOG(1) << "Registered flip window hotkey."; - } else { - VPLOG(1) << "Failed to register flip window hotkey."; - } - HRESULT hr = settings_handler_.Initialize(); - CheckHR(hr,"Failed to initialize settings handler."); - return hr; -} - -// We subclass the core window for moving the associated chrome window when the -// core window is moved around, typically in the snap view operation. The -// size changes are handled in the documented size changed event. -LRESULT CALLBACK ChromeAppView::CoreWindowProc( - HWND window, UINT message, WPARAM wp, LPARAM lp) { - - static const UINT kBrowserClosingMessage = - ::RegisterWindowMessage(L"DefaultBrowserClosing"); - - if (message == WM_WINDOWPOSCHANGED) { - WINDOWPOS* pos = reinterpret_cast<WINDOWPOS*>(lp); - if (!(pos->flags & SWP_NOMOVE)) { - DVLOG(1) << "WM_WINDOWPOSCHANGED. Moving the chrome window."; - globals.view->OnPositionChanged(pos->x, pos->y); - } - } else if (message == WM_HOTKEY && wp == kFlipWindowsHotKeyId) { - FlipFrameWindows(); - } else if (message == kBrowserClosingMessage) { - DVLOG(1) << "Received DefaultBrowserClosing window message."; - // Ensure that the view is uninitialized. The kBrowserClosingMessage - // means that the app is going to be terminated, i.e. the proper - // uninitialization sequence does not occur. - globals.view->Uninitialize(); - if (!globals.host_windows.empty()) { - EndChromeSession(); - } - } - return CallWindowProc(globals.g_core_proc, window, message, wp, lp); -} - -HRESULT ChromeAppView::OnSizeChanged(winui::Core::ICoreWindow* sender, - winui::Core::IWindowSizeChangedEventArgs* args) { - if (!globals.host_windows.size()) { - return S_OK; - } - - winfoundtn::Size size; - args->get_Size(&size); - - int cx = static_cast<int>(size.Width); - int cy = static_cast<int>(size.Height); - - if (!::SetWindowPos(globals.host_windows.front().first, NULL, 0, 0, cx, cy, - SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED)) { - DVLOG(1) << "SetWindowPos failed."; - } - DVLOG(1) << "size changed cx=" << cx; - DVLOG(1) << "size changed cy=" << cy; - - winui::ViewManagement::ApplicationViewState view_state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - app_view_->get_Value(&view_state); - - HWND top_level_frame = globals.host_windows.front().first; - if (view_state == winui::ViewManagement::ApplicationViewState_Snapped) { - DVLOG(1) << "Enabling metro snap mode."; - ::PostMessageW(top_level_frame, WM_SYSCOMMAND, IDC_METRO_SNAP_ENABLE, 0); - } else { - ::PostMessageW(top_level_frame, WM_SYSCOMMAND, IDC_METRO_SNAP_DISABLE, 0); - } - return S_OK; -} - -HRESULT ChromeAppView::OnPositionChanged(int x, int y) { - DVLOG(1) << __FUNCTION__; - - ::SetWindowPos(globals.host_windows.front().first, NULL, x, y, 0, 0, - SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSIZE); - return S_OK; -} - -HRESULT ChromeAppView::OnEdgeGestureCompleted( - winui::Input::IEdgeGesture* gesture, - winui::Input::IEdgeGestureEventArgs* args) { - DVLOG(1) << "edge gesture completed."; - - winui::ViewManagement::ApplicationViewState view_state = - winui::ViewManagement::ApplicationViewState_FullScreenLandscape; - app_view_->get_Value(&view_state); - // We don't want fullscreen chrome unless we are fullscreen metro. - if ((view_state == winui::ViewManagement::ApplicationViewState_Filled) || - (view_state == winui::ViewManagement::ApplicationViewState_Snapped)) { - DVLOG(1) << "No full screen in snapped view state:" << view_state; - return S_OK; - } - - // Deactivate anything pending, e.g., the wrench or a context menu. - BOOL success = ::ReleaseCapture(); - DCHECK(success) << "Couldn't ReleaseCapture() before going full screen"; - - DVLOG(1) << "Going full screen."; - ::PostMessageW(globals.host_windows.front().first, WM_SYSCOMMAND, - IDC_FULLSCREEN, 0); - return S_OK; -} - -HRESULT ChromeAppView::OnShareDataRequested( - winapp::DataTransfer::IDataTransferManager* data_transfer_mgr, - winapp::DataTransfer::IDataRequestedEventArgs* event_args) { - - DVLOG(1) << "Share data requested."; - - // The current tab info is retrieved from Chrome via a registered window - // message. - - static const UINT get_current_tab_info = - RegisterWindowMessage(kMetroGetCurrentTabInfoMessage); - - static const int kGetTabInfoTimeoutMs = 1000; - - mswr::ComPtr<winapp::DataTransfer::IDataRequest> data_request; - HRESULT hr = event_args->get_Request(&data_request); - CheckHR(hr); - - mswr::ComPtr<winapp::DataTransfer::IDataPackage> data_package; - hr = data_request->get_Data(&data_package); - CheckHR(hr); - - base::win::CurrentTabInfo current_tab_info; - current_tab_info.title = NULL; - current_tab_info.url = NULL; - - DWORD_PTR result = 0; - - if (!SendMessageTimeout(globals.host_windows.front().first, - get_current_tab_info, - reinterpret_cast<WPARAM>(¤t_tab_info), - 0, - SMTO_ABORTIFHUNG, - kGetTabInfoTimeoutMs, - &result)) { - VPLOG(1) << "Failed to retrieve tab info from chrome."; - return E_FAIL; - } - - if (!current_tab_info.title || !current_tab_info.url) { - DVLOG(1) << "Failed to retrieve tab info from chrome."; - return E_FAIL; - } - - base::string16 current_title(current_tab_info.title); - base::string16 current_url(current_tab_info.url); - - LocalFree(current_tab_info.title); - LocalFree(current_tab_info.url); - - mswr::ComPtr<winapp::DataTransfer::IDataPackagePropertySet> data_properties; - hr = data_package->get_Properties(&data_properties); - - mswrw::HString title; - title.Attach(MakeHString(current_title)); - data_properties->put_Title(title.Get()); - - mswr::ComPtr<winfoundtn::IUriRuntimeClassFactory> uri_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Foundation_Uri, - uri_factory.GetAddressOf()); - CheckHR(hr); - - mswrw::HString url; - url.Attach(MakeHString(current_url)); - mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; - hr = uri_factory->CreateUri(url.Get(), &uri); - CheckHR(hr); - - hr = data_package->SetUri(uri.Get()); - CheckHR(hr); - - return S_OK; -} - -void ChromeAppView::HandleInputPaneVisible(const RECT& osk_rect) { - DCHECK(!osk_visible_notification_received_); - - DVLOG(1) << __FUNCTION__; - DVLOG(1) << "OSK width:" << osk_rect.right - osk_rect.left; - DVLOG(1) << "OSK height:" << osk_rect.bottom - osk_rect.top; - - globals.host_windows.front().second = false; - - POINT cursor_pos = {0}; - GetCursorPos(&cursor_pos); - - osk_offset_adjustment_ = 0; - - if (::PtInRect(&osk_rect, cursor_pos)) { - DVLOG(1) << "OSK covering focus point."; - int osk_height = osk_rect.bottom - osk_rect.top; - - osk_offset_adjustment_ = osk_height + kOSKAdjustmentOffset; - - DVLOG(1) << "Scrolling window by offset: " << osk_offset_adjustment_; - ::ScrollWindowEx(globals.host_windows.front().first, - 0, - -osk_offset_adjustment_, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE | SW_SCROLLCHILDREN); - - globals.host_windows.front().second = true; - } - osk_visible_notification_received_ = true; -} - -void ChromeAppView::HandleInputPaneHidden(const RECT& osk_rect) { - DCHECK(osk_visible_notification_received_); - DVLOG(1) << __FUNCTION__; - DVLOG(1) << "OSK width:" << osk_rect.right - osk_rect.left; - DVLOG(1) << "OSK height:" << osk_rect.bottom - osk_rect.top; - osk_visible_notification_received_ = false; - if (globals.host_windows.front().second == true) { - - if (osk_offset_adjustment_) { - DVLOG(1) << "Restoring scrolled window offset: " - << osk_offset_adjustment_; - - ::ScrollWindowEx(globals.host_windows.front().first, - 0, - osk_offset_adjustment_, - NULL, - NULL, - NULL, - NULL, - SW_INVALIDATE | SW_SCROLLCHILDREN); - } - - globals.host_windows.front().second = false; - } -} - -HRESULT ChromeAppView::OnInputPaneVisible( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args) { - DVLOG(1) << __FUNCTION__; - return S_OK; -} - -HRESULT ChromeAppView::OnInputPaneHiding( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args) { - DVLOG(1) << __FUNCTION__; - return S_OK; -} - -/////////////////////////////////////////////////////////////////////////////// - -ChromeAppViewFactory::ChromeAppViewFactory( - winapp::Core::ICoreApplication* icore_app, - LPTHREAD_START_ROUTINE host_main, - void* host_context) { - globals.host_main = host_main; - globals.host_context = host_context; - mswr::ComPtr<winapp::Core::ICoreApplication> core_app(icore_app); - mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit; - CheckHR(core_app.As(&app_exit)); - globals.app_exit = app_exit.Detach(); -} - -IFACEMETHODIMP -ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { - globals.view = mswr::Make<ChromeAppView>().Detach(); - *view = globals.view; - return (*view) ? S_OK : E_OUTOFMEMORY; -} diff --git a/win8/metro_driver/chrome_app_view.h b/win8/metro_driver/chrome_app_view.h deleted file mode 100644 index 2620d008..0000000 --- a/win8/metro_driver/chrome_app_view.h +++ /dev/null @@ -1,172 +0,0 @@ -// 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_H_ -#define WIN8_METRO_DRIVER_CHROME_APP_VIEW_H_ - -#include <windows.applicationmodel.core.h> -#include <windows.ui.core.h> -#include <windows.ui.input.h> -#include <windows.ui.viewmanagement.h> - -#include <list> -#include <map> -#include <string> -#include <utility> - -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" -#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/metro_dialog_box.h" -#include "win8/metro_driver/settings_handler.h" -#include "win8/metro_driver/toast_notification_handler.h" - -namespace IPC { - class Listener; - class ChannelProxy; -} - -class ChromeAppView - : public mswr::RuntimeClass<winapp::Core::IFrameworkView> { - public: - ChromeAppView(); - ~ChromeAppView(); - - // IViewProvider overrides. - IFACEMETHOD(Initialize)(winapp::Core::ICoreApplicationView* view); - IFACEMETHOD(SetWindow)(winui::Core::ICoreWindow* window); - IFACEMETHOD(Load)(HSTRING entryPoint); - IFACEMETHOD(Run)(); - IFACEMETHOD(Uninitialize)(); - - static LRESULT CALLBACK CoreWindowProc(HWND window, UINT message, WPARAM wp, - LPARAM lp); - - bool osk_visible_notification_received() const { - return osk_visible_notification_received_; - } - - // Displays the notification. - void DisplayNotification( - const ToastNotificationHandler::DesktopNotification& notification); - - // Cancels the notification. - void CancelNotification(const std::string& notification); - - // Returns true if the notification passed in is valid. - bool IsValidNotification(const std::string& notification); - - // Displays a dialog box. - void ShowDialogBox(const MetroDialogBox::DialogBoxInfo& dialog_box_info); - // Dismisses the dialog box. - void DismissDialogBox(); - - // Helper function to unsnap the chrome metro app if it is snapped. - // Returns S_OK on success. - static HRESULT Unsnap(); - - // Notification from chrome that a full screen operation is being performed. - void SetFullscreen(bool fullscreen); - - // Returns the current view state of the chrome window. - winui::ViewManagement::ApplicationViewState GetViewState(); - - HWND core_window_hwnd() { return core_window_hwnd_; } - - private: - HRESULT OnActivate(winapp::Core::ICoreApplicationView* view, - winapp::Activation::IActivatedEventArgs* args); - - HRESULT OnSizeChanged(winui::Core::ICoreWindow* sender, - winui::Core::IWindowSizeChangedEventArgs* args); - - HRESULT OnEdgeGestureCompleted(winui::Input::IEdgeGesture* gesture, - winui::Input::IEdgeGestureEventArgs* args); - - HRESULT OnShareDataRequested( - winapp::DataTransfer::IDataTransferManager* data_transfer_mgr, - winapp::DataTransfer::IDataRequestedEventArgs* event_args); - - HRESULT OnInputPaneVisible( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args); - - HRESULT OnInputPaneHiding( - winui::ViewManagement::IInputPane* input_pane, - winui::ViewManagement::IInputPaneVisibilityEventArgs* event_args); - - HRESULT OnPositionChanged(int x, int y); - - void CheckForOSKActivation(); - - HRESULT RegisterInputPaneNotifications(); - - void HandleInputPaneVisible(const RECT& osk_rect); - void HandleInputPaneHidden(const RECT& osk_rect); - - mswr::ComPtr<winui::Core::ICoreWindow> window_; - mswr::ComPtr<winapp::Core::ICoreApplicationView> view_; - EventRegistrationToken activated_token_; - EventRegistrationToken edgeevent_token_; - EventRegistrationToken sizechange_token_; - EventRegistrationToken share_data_requested_token_; - EventRegistrationToken input_pane_visible_token_; - EventRegistrationToken input_pane_hiding_token_; - EventRegistrationToken app_exit_token_; - - // The actual window behind the view surface. - HWND core_window_hwnd_; - - ChromeUrlLaunchHandler url_launch_handler_; - metro_driver::DevicesHandler devices_handler_; - SettingsHandler settings_handler_; - mswr::ComPtr<winui::ViewManagement::IInputPane> input_pane_; - mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> app_view_; - - bool osk_visible_notification_received_; - - // map of notification id to the ToastNotificationHandler instance. - typedef std::map<std::string, scoped_ptr<ToastNotificationHandler> > - NotificationMap; - NotificationMap notification_map_; - - // Synchronizes access to the notification_map_ member. - base::Lock notification_lock_; - - // If the OSK covers the input area we scroll the window by the height of the - // OSK + an additional offset. This member holds this offset. Set to 0 if the - // window was not scrolled. - int osk_offset_adjustment_; - - MetroDialogBox dialog_box_; -}; - -// Global information used across the metro driver. -struct Globals { - LPTHREAD_START_ROUTINE host_main; - void* host_context; - // The pair below contains the HWND and a bool which indicates whether the - // window was displaced to ensure that the focused region is visible when - // the OSK is displayed. - std::list<std::pair<HWND, bool> > host_windows; - HANDLE host_thread; - ChromeAppView* view; - WNDPROC g_core_proc; - base::string16 navigation_url; - base::string16 search_string; - winapp::Activation::ApplicationExecutionState previous_state; - winapp::Activation::ActivationKind initial_activation_kind; - bool is_initial_activation; - // This message loop lives in the app view's thread. Some operations have - // to be initiated from that thread, notably spawning file pickers. - base::SingleThreadTaskRunner* appview_task_runner; - winapp::Core::ICoreApplicationExit* app_exit; - base::string16 metro_command_line_switches; -}; - -extern Globals globals; - -#endif // WIN8_METRO_DRIVER_CHROME_APP_VIEW_H_ diff --git a/win8/metro_driver/chrome_url_launch_handler.cc b/win8/metro_driver/chrome_url_launch_handler.cc deleted file mode 100644 index f37706c..0000000 --- a/win8/metro_driver/chrome_url_launch_handler.cc +++ /dev/null @@ -1,207 +0,0 @@ -// 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 "stdafx.h" -#include "chrome_url_launch_handler.h" -#include "chrome_app_view.h" - -#include <assert.h> -#include <shellapi.h> -#include <shlobj.h> -#include <string> - -#include "base/command_line.h" - -#include "winrt_utils.h" - -typedef winfoundtn::ITypedEventHandler< - winapp::Search::SearchPane*, - winapp::Search::SearchPaneQuerySubmittedEventArgs*> QuerySubmittedHandler; - -ChromeUrlLaunchHandler::ChromeUrlLaunchHandler() { - globals.is_initial_activation = true; - globals.initial_activation_kind = winapp::Activation::ActivationKind_Launch; - DVLOG(1) << __FUNCTION__; -} - -// TODO(ananta) -// Remove this once we consolidate metro driver with chrome. -const wchar_t kMetroNavigationAndSearchMessage[] = - L"CHROME_METRO_NAV_SEARCH_REQUEST"; - -ChromeUrlLaunchHandler::~ChromeUrlLaunchHandler() { - DVLOG(1) << __FUNCTION__; - search_pane_->remove_QuerySubmitted(query_submitted_token_); -} - -HRESULT ChromeUrlLaunchHandler::Initialize() { - mswr::ComPtr<winapp::Search::ISearchPaneStatics> search_pane_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_ApplicationModel_Search_SearchPane, - search_pane_statics.GetAddressOf()); - CheckHR(hr, "Failed to activate ISearchPaneStatics"); - - hr = search_pane_statics->GetForCurrentView(&search_pane_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get search pane for current view"; - return hr; - } - - hr = search_pane_->add_QuerySubmitted(mswr::Callback<QuerySubmittedHandler>( - this, - &ChromeUrlLaunchHandler::OnQuerySubmitted).Get(), - &query_submitted_token_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to register for Query Submitted event"; - return hr; - } - return hr; -} - -HRESULT ChromeUrlLaunchHandler::OnQuerySubmitted( - winapp::Search::ISearchPane* search_pane, - winapp::Search::ISearchPaneQuerySubmittedEventArgs* args) { - DVLOG(1) << "OnQuerySubmitted"; - HandleSearchRequest(args); - return S_OK; -} - -template<class T> -void ChromeUrlLaunchHandler::HandleSearchRequest(T* args) { - DVLOG(1) << __FUNCTION__; - mswrw::HString search_string; - args->get_QueryText(search_string.GetAddressOf()); - base::string16 search_text(MakeStdWString(search_string.Get())); - globals.search_string = search_text; - DVLOG(1) << search_text.c_str(); - // If this is the initial activation then we wait for Chrome to initiate the - // navigation. In all other cases navigate right away. - if (!globals.is_initial_activation) - InitiateNavigationOrSearchRequest(NULL, globals.search_string.c_str()); -} - -void ChromeUrlLaunchHandler::HandleProtocolLaunch( - winapp::Activation::IProtocolActivatedEventArgs* args) { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; - args->get_Uri(&uri); - mswrw::HString url; - uri->get_AbsoluteUri(url.GetAddressOf()); - base::string16 actual_url(MakeStdWString(url.Get())); - globals.navigation_url = actual_url; - - // If this is the initial activation then we wait for Chrome to initiate the - // navigation. In all other cases navigate right away. - if (!globals.is_initial_activation) - InitiateNavigationOrSearchRequest(globals.navigation_url.c_str(), 0); -} - -// |launch_args| is an encoded command line, minus the executable name. To -// find the URL to launch the first argument is used. If any other parameters -// are encoded in |launch_args| they are ignored. -base::string16 ChromeUrlLaunchHandler::GetUrlFromLaunchArgs( - const base::string16& launch_args) { - if (launch_args == L"opennewwindow") { - VLOG(1) << "Returning new tab url"; - return L"chrome://newtab"; - } - base::string16 dummy_command_line(L"dummy.exe "); - dummy_command_line.append(launch_args); - base::CommandLine command_line = - base::CommandLine::FromString(dummy_command_line); - base::CommandLine::StringVector args = command_line.GetArgs(); - if (args.size() > 0) - return args[0]; - - return base::string16(); -} - -void ChromeUrlLaunchHandler::HandleLaunch( - winapp::Activation::ILaunchActivatedEventArgs* args) { - mswrw::HString launch_args; - args->get_Arguments(launch_args.GetAddressOf()); - base::string16 actual_launch_args(MakeStdWString(launch_args.Get())); - globals.navigation_url = GetUrlFromLaunchArgs(actual_launch_args); - DVLOG(1) << __FUNCTION__ << ", launch_args=" << actual_launch_args - << ", url=" << globals.navigation_url - << ", is_initial_activation=" << globals.is_initial_activation; - - // If this is the initial launch then we wait for Chrome to initiate the - // navigation. In all other cases navigate right away. - if (!globals.is_initial_activation) - InitiateNavigationOrSearchRequest(globals.navigation_url.c_str(), 0); -} - -void ChromeUrlLaunchHandler::Activate( - winapp::Activation::IActivatedEventArgs* args) { - winapp::Activation::ActivationKind activation_kind; - CheckHR(args->get_Kind(&activation_kind)); - - DVLOG(1) << __FUNCTION__ << ", activation_kind=" << activation_kind; - - if (globals.is_initial_activation) - globals.initial_activation_kind = activation_kind; - - if (activation_kind == winapp::Activation::ActivationKind_Launch) { - mswr::ComPtr<winapp::Activation::ILaunchActivatedEventArgs> launch_args; - if (args->QueryInterface(winapp::Activation::IID_ILaunchActivatedEventArgs, - &launch_args) == S_OK) { - DVLOG(1) << "Activate: ActivationKind_Launch"; - HandleLaunch(launch_args.Get()); - } - } else if (activation_kind == - winapp::Activation::ActivationKind_Search) { - mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args; - if (args->QueryInterface(winapp::Activation::IID_ISearchActivatedEventArgs, - &search_args) == S_OK) { - DVLOG(1) << "Activate: ActivationKind_Search"; - HandleSearchRequest(search_args.Get()); - } - } else if (activation_kind == - winapp::Activation::ActivationKind_Protocol) { - mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs> - protocol_args; - if (args->QueryInterface( - winapp::Activation::IID_IProtocolActivatedEventArgs, - &protocol_args) == S_OK) { - DVLOG(1) << "Activate: ActivationKind_Protocol"; - HandleProtocolLaunch(protocol_args.Get()); - } - } else { - DVLOG(1) << "Activate: Unhandled mode: " << activation_kind; - } -} - -void ChromeUrlLaunchHandler::InitiateNavigationOrSearchRequest( - const wchar_t* url, const wchar_t* search_string) { - DVLOG(1) << __FUNCTION__; - if (!url && !search_string) { - NOTREACHED(); - return; - } - - DVLOG(1) << (url ? url : L"NULL url"); - DVLOG(1) << (search_string ? search_string : L"NULL search string"); - - if (globals.host_windows.empty()) { - DVLOG(1) << "No chrome windows registered. Ignoring nav request"; - return; - } - - // Custom registered message to navigate or search in chrome. WPARAM - // points to the URL and LPARAM contains the search string. They are - // mutually exclusive. - static const UINT navigation_search_message = - RegisterWindowMessage(kMetroNavigationAndSearchMessage); - - if (url) { - VLOG(1) << "Posting url:" << url; - PostMessage(globals.host_windows.front().first, navigation_search_message, - reinterpret_cast<WPARAM>(url), 0); - } else { - VLOG(1) << "Posting search string:" << search_string; - PostMessage(globals.host_windows.front().first, navigation_search_message, - 0, reinterpret_cast<LPARAM>(search_string)); - } -} diff --git a/win8/metro_driver/chrome_url_launch_handler.h b/win8/metro_driver/chrome_url_launch_handler.h deleted file mode 100644 index 093b57b..0000000 --- a/win8/metro_driver/chrome_url_launch_handler.h +++ /dev/null @@ -1,58 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_CHROME_URL_LAUNCH_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_CHROME_URL_LAUNCH_HANDLER_H_ - -#include <string> -#include <windows.applicationmodel.core.h> -#include <Windows.applicationModel.search.h> -#include <windows.ui.core.h> - -#include "winrt_utils.h" - -// This class handles the various flavors of URL launches in metro, i.e. -// via the search charm, via a url being navigated from a metro app, etc. -class ChromeUrlLaunchHandler { - public: - ChromeUrlLaunchHandler(); - ~ChromeUrlLaunchHandler(); - - HRESULT Initialize(); - - // If metro chrome was launched due to a URL navigation/search request then - // the navigation should be done when the frame window is initialized. This - // function is called to complete the pending navigation when we receive a - // notification from chrome that the frame window is initialized. - void PerformPendingNavigation(); - - void Activate(winapp::Activation::IActivatedEventArgs* args); - - private: - // Invoked when we receive search notifications in metro chrome. - template<class T> void HandleSearchRequest(T* args); - - HRESULT OnQuerySubmitted( - winapp::Search::ISearchPane* search_pane, - winapp::Search::ISearchPaneQuerySubmittedEventArgs* args); - - base::string16 GetUrlFromLaunchArgs(const base::string16& launch_args); - - // Invoked when a url is navigated from a metro app or in the metro - // shelf. - void HandleProtocolLaunch( - winapp::Activation::IProtocolActivatedEventArgs* args); - - // Invoked when the app is launched normally - void HandleLaunch(winapp::Activation::ILaunchActivatedEventArgs* args); - - // Helper function to initiate a navigation or search request in chrome. - void InitiateNavigationOrSearchRequest(const wchar_t* url, - const wchar_t* search_string); - - Microsoft::WRL::ComPtr<winapp::Search::ISearchPane> search_pane_; - EventRegistrationToken query_submitted_token_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_CHROME_URL_LAUNCH_HANDLER_H_ diff --git a/win8/metro_driver/devices_handler.cc b/win8/metro_driver/devices_handler.cc deleted file mode 100644 index 20fd413..0000000 --- a/win8/metro_driver/devices_handler.cc +++ /dev/null @@ -1,23 +0,0 @@ -// 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 "stdafx.h" -#include "win8/metro_driver/devices_handler.h" - -#include "base/logging.h" - -namespace metro_driver { - -DevicesHandler::DevicesHandler() { -} - -DevicesHandler::~DevicesHandler() { -} - -HRESULT DevicesHandler::Initialize(winui::Core::ICoreWindow* window) { - HRESULT hr = print_handler_.Initialize(window); - return hr; -} - -} // namespace metro_driver diff --git a/win8/metro_driver/devices_handler.h b/win8/metro_driver/devices_handler.h deleted file mode 100644 index ea3b140..0000000 --- a/win8/metro_driver/devices_handler.h +++ /dev/null @@ -1,31 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_DEVICES_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_DEVICES_HANDLER_H_ - -#include <windows.ui.core.h> - -#include "base/macros.h" -#include "win8/metro_driver/print_handler.h" - -namespace metro_driver { - -// This class handles the devices charm. -class DevicesHandler { - public: - DevicesHandler(); - ~DevicesHandler(); - - HRESULT Initialize(winui::Core::ICoreWindow* window); - - private: - PrintHandler print_handler_; - - DISALLOW_COPY_AND_ASSIGN(DevicesHandler); -}; - -} // namespace metro_driver - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_DEVICES_HANDLER_H_ diff --git a/win8/metro_driver/direct3d_helper.cc b/win8/metro_driver/direct3d_helper.cc deleted file mode 100644 index b19c57d..0000000 --- a/win8/metro_driver/direct3d_helper.cc +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 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 "stdafx.h" -#include <corewindow.h> -#include <windows.applicationmodel.core.h> -#include <windows.graphics.display.h> - -#include "win8/metro_driver/direct3d_helper.h" -#include "base/logging.h" -#include "base/win/windows_version.h" -#include "ui/gfx/win/dpi.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -void CheckIfFailed(HRESULT hr) { - DCHECK(!FAILED(hr)); - if (FAILED(hr)) - DVLOG(0) << "Direct3D call failed, hr = " << hr; -} - -float ConvertDipsToPixels(float dips) { - return floor(dips * gfx::GetDPIScale() + 0.5f); -} - -} - -namespace metro_driver { - -Direct3DHelper::Direct3DHelper() { -} - -Direct3DHelper::~Direct3DHelper() { -} - -void Direct3DHelper::Initialize(winui::Core::ICoreWindow* window) { - window_ = window; - CreateDeviceResources(); - CreateWindowSizeDependentResources(); -} - -// TODO(scottmg): Need to handle resize messages and recreation. - -void Direct3DHelper::CreateDeviceResources() { - unsigned int creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; - D3D_FEATURE_LEVEL feature_levels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, - }; - - mswr::ComPtr<ID3D11Device> device; - mswr::ComPtr<ID3D11DeviceContext> context; - CheckIfFailed( - D3D11CreateDevice( - nullptr, - D3D_DRIVER_TYPE_HARDWARE, - nullptr, - creation_flags, - feature_levels, - ARRAYSIZE(feature_levels), - D3D11_SDK_VERSION, - &device, - &feature_level_, - &context)); - CheckIfFailed(device.As(&d3d_device_)); - CheckIfFailed(context.As(&d3d_context_)); -} - -void Direct3DHelper::CreateWindowSizeDependentResources() { - 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. - - if (swap_chain_ != nullptr) { - // TODO(scottmg): Resize if it already exists. - NOTIMPLEMENTED(); - } else { - DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = { 0 }; - swap_chain_desc.Width = window_width; - swap_chain_desc.Height = window_height; - swap_chain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - swap_chain_desc.Stereo = false; - swap_chain_desc.SampleDesc.Count = 1; - swap_chain_desc.SampleDesc.Quality = 0; - swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swap_chain_desc.BufferCount = 2; // TODO(scottmg): Probably 1 is fine. - swap_chain_desc.Scaling = DXGI_SCALING_NONE; - swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - swap_chain_desc.Flags = 0; - - mswr::ComPtr<IDXGIDevice1> dxgi_device; - CheckIfFailed(d3d_device_.As(&dxgi_device)); - - mswr::ComPtr<IDXGIAdapter> dxgi_adapter; - CheckIfFailed(dxgi_device->GetAdapter(&dxgi_adapter)); - - mswr::ComPtr<IDXGIFactory2> dxgi_factory; - CheckIfFailed(dxgi_adapter->GetParent( - __uuidof(IDXGIFactory2), &dxgi_factory)); - - 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_)); - // Prevent DXGI from monitoring an application message queue and thus - // attempt mode changes. For e.g. Alt + Enter by default causes - // DXGI to attempt to take the window fullscreen. - CheckIfFailed(dxgi_factory->MakeWindowAssociation( - window, DXGI_MWA_NO_WINDOW_CHANGES)); - } - } -} - -} // namespace metro_driver diff --git a/win8/metro_driver/direct3d_helper.h b/win8/metro_driver/direct3d_helper.h deleted file mode 100644 index 863a146..0000000 --- a/win8/metro_driver/direct3d_helper.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 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_DIRECT3D_HELPER_ -#define WIN8_METRO_DRIVER_DIRECT3D_HELPER_ - - -#include <windows.ui.core.h> -#include <windows.foundation.h> -#include <d3d11_1.h> - -#include "base/macros.h" - -namespace metro_driver { - -// We need to initalize a Direct3D device and swapchain so that the browser -// can Present to our HWND. This class takes care of creating and keeping the -// swapchain up to date. -class Direct3DHelper { - public: - Direct3DHelper(); - ~Direct3DHelper(); - - void Initialize(winui::Core::ICoreWindow* window); - - private: - void CreateDeviceResources(); - void CreateWindowSizeDependentResources(); - - winui::Core::ICoreWindow* window_; - - mswr::ComPtr<ID3D11Device1> d3d_device_; - mswr::ComPtr<ID3D11DeviceContext1> d3d_context_; - mswr::ComPtr<IDXGISwapChain1> swap_chain_; - D3D_FEATURE_LEVEL feature_level_; - - ABI::Windows::Foundation::Rect window_bounds_; - - DISALLOW_COPY_AND_ASSIGN(Direct3DHelper); -}; - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_DIRECT3D_HELPER_ diff --git a/win8/metro_driver/display_properties.cc b/win8/metro_driver/display_properties.cc deleted file mode 100644 index e1b7ed5..0000000 --- a/win8/metro_driver/display_properties.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 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 "stdafx.h" - -#include <windows.h> -#include <wrl\implements.h> -#include <wrl\wrappers\corewrappers.h> -#include <windows.foundation.h> -#include <windows.graphics.display.h> -#include "base/win/windows_version.h" -#include "ui/gfx/win/dpi.h" -#include "winrt_utils.h" - -float GetModernUIScale() { - if (base::win::GetVersion() >= base::win::VERSION_WIN8) { - Microsoft::WRL::ComPtr< - ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> - display_properties; - if (SUCCEEDED(winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Display_DisplayProperties, - display_properties.GetAddressOf()))) { - ABI::Windows::Graphics::Display::ResolutionScale resolution_scale; - if (SUCCEEDED(display_properties->get_ResolutionScale(&resolution_scale))) - return static_cast<float>(resolution_scale) / 100.0f; - } - } - return gfx::GetDPIScale(); -} diff --git a/win8/metro_driver/display_properties.h b/win8/metro_driver/display_properties.h deleted file mode 100644 index 1491b3f..0000000 --- a/win8/metro_driver/display_properties.h +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 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 CHROME_BROWSER_UI_METRO_DRIVER_DISPLAY_PROPERTIES_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_DISPLAY_PROPERTIES_H_ - -// Determines the scale factor used in the modern/metro ui. 1.0 means unscaled. -extern "C" __declspec(dllexport) float GetModernUIScale(); - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_DISPLAY_PROPERTIES_H_ diff --git a/win8/metro_driver/ime/BUILD.gn b/win8/metro_driver/ime/BUILD.gn deleted file mode 100644 index 63ebd99..0000000 --- a/win8/metro_driver/ime/BUILD.gn +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2015 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. - -source_set("ime") { - visibility = [ "//win8/metro_driver/*" ] - sources = [ - "ime_popup_monitor.cc", - "ime_popup_monitor.h", - "ime_popup_observer.h", - "input_scope.cc", - "input_scope.h", - "input_source.cc", - "input_source.h", - "input_source_observer.h", - "text_service.cc", - "text_service.h", - "text_service_delegate.h", - "text_store.cc", - "text_store.h", - "text_store_delegate.h", - ] - - deps = [ - "//base", - "//ui/base", - "//ui/metro_viewer", - ] -} diff --git a/win8/metro_driver/ime/ime.gypi b/win8/metro_driver/ime/ime.gypi deleted file mode 100644 index f5d489c..0000000 --- a/win8/metro_driver/ime/ime.gypi +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2013 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. - -{ - # GN version: //win8/metro_driver/ime - 'sources': [ - 'ime_popup_monitor.cc', - 'ime_popup_monitor.h', - 'ime_popup_observer.h', - 'input_scope.cc', - 'input_scope.h', - 'input_source.cc', - 'input_source.h', - 'input_source_observer.h', - 'text_service.cc', - 'text_service.h', - 'text_service_delegate.h', - 'text_store.cc', - 'text_store.h', - 'text_store_delegate.h', - ], -} diff --git a/win8/metro_driver/ime/ime_popup_monitor.cc b/win8/metro_driver/ime/ime_popup_monitor.cc deleted file mode 100644 index a478607..0000000 --- a/win8/metro_driver/ime/ime_popup_monitor.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2013 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/ime/ime_popup_monitor.h" - -#include <windows.h> - -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "win8/metro_driver/ime/ime_popup_observer.h" - -namespace metro_driver { -namespace { - -ImePopupObserver* g_observer_ = NULL; -HWINEVENTHOOK g_hook_handle_ = NULL; - -void CALLBACK ImeEventCallback(HWINEVENTHOOK win_event_hook_handle, - DWORD event, - HWND window_handle, - LONG object_id, - LONG child_id, - DWORD event_thread, - DWORD event_time) { - // This function is registered to SetWinEventHook to be called back on the UI - // thread. - DCHECK(base::MessageLoopForUI::IsCurrent()); - - if (!g_observer_) - return; - switch (event) { - case EVENT_OBJECT_IME_SHOW: - g_observer_->OnImePopupChanged(ImePopupObserver::kPopupShown); - return; - case EVENT_OBJECT_IME_HIDE: - g_observer_->OnImePopupChanged(ImePopupObserver::kPopupHidden); - return; - case EVENT_OBJECT_IME_CHANGE: - g_observer_->OnImePopupChanged(ImePopupObserver::kPopupUpdated); - return; - } -} - -} // namespace - -void AddImePopupObserver(ImePopupObserver* observer) { - CHECK(g_observer_ == NULL) - << "Currently only one observer is supported at the same time."; - g_observer_ = observer; - - // IMEs running under immersive mode are supposed to generate WinEvent - // whenever their popup UI such as candidate window is shown, updated, and - // hidden to support accessibility applications. - // http://msdn.microsoft.com/en-us/library/windows/apps/hh967425.aspx#accessibility - // Note that there is another mechanism in TSF, called ITfUIElementSink, to - // subscribe when the visibility of an IME's UI element is changed. However, - // MS-IME running under immersive mode does not fully support this API. - // Thus, WinEvent is more reliable for this purpose. - g_hook_handle_ = SetWinEventHook( - EVENT_OBJECT_IME_SHOW, - EVENT_OBJECT_IME_CHANGE, - NULL, - ImeEventCallback, - GetCurrentProcessId(), // monitor the metro_driver process only - 0, // hook all threads because MS-IME emits WinEvent in a worker thread - WINEVENT_OUTOFCONTEXT); // allows us to receive message in the UI thread - LOG_IF(ERROR, !g_hook_handle_) << "SetWinEventHook failed."; -} - -void RemoveImePopupObserver(ImePopupObserver* observer) { - if (g_observer_ != observer) - return; - g_observer_ = NULL; - if (!g_hook_handle_) - return; - const bool unhook_succeeded = !!UnhookWinEvent(g_hook_handle_); - LOG_IF(ERROR, !unhook_succeeded) << "UnhookWinEvent failed."; - g_hook_handle_ = NULL; -} - -} // namespace metro_driver diff --git a/win8/metro_driver/ime/ime_popup_monitor.h b/win8/metro_driver/ime/ime_popup_monitor.h deleted file mode 100644 index 3bf6558..0000000 --- a/win8/metro_driver/ime/ime_popup_monitor.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2013 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_IME_IME_POPUP_MONITOR_H_ -#define WIN8_METRO_DRIVER_IME_IME_POPUP_MONITOR_H_ - -namespace metro_driver { - -class ImePopupObserver; - -// Adds/Removes ImePopupObserver. Currently only one observer is supported at -// the same time. -void AddImePopupObserver(ImePopupObserver* observer); -void RemoveImePopupObserver(ImePopupObserver* observer); - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_IME_POPUP_MONITOR_H_ diff --git a/win8/metro_driver/ime/ime_popup_observer.h b/win8/metro_driver/ime/ime_popup_observer.h deleted file mode 100644 index b871084..0000000 --- a/win8/metro_driver/ime/ime_popup_observer.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2013 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_IME_IME_POPUP_OBSERVER_H_ -#define WIN8_METRO_DRIVER_IME_IME_POPUP_OBSERVER_H_ - -namespace metro_driver { - -// An observer interface implemented by objects that want to be informed when -// an IME shows or hides its popup window. -class ImePopupObserver { - public: - enum EventType { - kPopupShown, - kPopupHidden, - kPopupUpdated, - }; - virtual ~ImePopupObserver() {} - - // Called whenever an IME's popup window is changed. - virtual void OnImePopupChanged(EventType type) = 0; -}; - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_IME_POPUP_OBSERVER_H_ diff --git a/win8/metro_driver/ime/input_scope.cc b/win8/metro_driver/ime/input_scope.cc deleted file mode 100644 index 43c85bf..0000000 --- a/win8/metro_driver/ime/input_scope.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2013 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/ime/input_scope.h" - -#include <atlbase.h> -#include <atlcom.h> - -#include "base/logging.h" -#include "base/macros.h" -#include "ui/base/win/atl_module.h" - -namespace metro_driver { -namespace { - -// An implementation of ITfInputScope interface. -// This implementation only covers ITfInputScope::GetInputScopes since built-in -// on-screen keyboard on Windows 8+ changes its layout depending on the returned -// value of this method. -// Although other advanced features of ITfInputScope such as phase list or -// regex support might be useful for IMEs or on-screen keyboards in future, -// no IME seems to be utilizing such features as of Windows 8.1. -class ATL_NO_VTABLE InputScopeImpl - : public CComObjectRootEx<CComMultiThreadModel>, - public ITfInputScope { - public: - InputScopeImpl() {} - - BEGIN_COM_MAP(InputScopeImpl) - COM_INTERFACE_ENTRY(ITfInputScope) - END_COM_MAP() - - void Initialize(const std::vector<InputScope>& input_scopes) { - input_scopes_ = input_scopes; - } - - private: - // ITfInputScope overrides: - STDMETHOD(GetInputScopes)(InputScope** input_scopes, UINT* count) override { - if (!count || !input_scopes) - return E_INVALIDARG; - *input_scopes = static_cast<InputScope*>( - CoTaskMemAlloc(sizeof(InputScope) * input_scopes_.size())); - if (!input_scopes) { - *count = 0; - return E_OUTOFMEMORY; - } - std::copy(input_scopes_.begin(), input_scopes_.end(), *input_scopes); - *count = static_cast<UINT>(input_scopes_.size()); - return S_OK; - } - STDMETHOD(GetPhrase)(BSTR** phrases, UINT* count) override { - return E_NOTIMPL; - } - STDMETHOD(GetRegularExpression)(BSTR* regexp) override { - return E_NOTIMPL; - } - STDMETHOD(GetSRGS)(BSTR* srgs) override { - return E_NOTIMPL; - } - STDMETHOD(GetXML)(BSTR* xml) override { - return E_NOTIMPL; - } - - // Data which ITfInputScope::GetInputScopes should return. - std::vector<InputScope> input_scopes_; - - DISALLOW_COPY_AND_ASSIGN(InputScopeImpl); -}; - -} // namespace - -base::win::ScopedComPtr<ITfInputScope> -CreteInputScope(const std::vector<InputScope>& input_scopes) { - ui::win::CreateATLModuleIfNeeded(); - CComObject<InputScopeImpl>* object = NULL; - HRESULT hr = CComObject<InputScopeImpl>::CreateInstance(&object); - if (FAILED(hr)) { - LOG(ERROR) << "CComObject<InputScopeImpl>::CreateInstance failed. hr = " - << hr; - return base::win::ScopedComPtr<ITfInputScope>(); - } - object->Initialize(input_scopes); - return base::win::ScopedComPtr<ITfInputScope>(object); -} - -} // namespace metro_driver diff --git a/win8/metro_driver/ime/input_scope.h b/win8/metro_driver/ime/input_scope.h deleted file mode 100644 index 99ed283..0000000 --- a/win8/metro_driver/ime/input_scope.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013 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_IME_INPUT_SCOPE_H_ -#define WIN8_METRO_DRIVER_IME_INPUT_SCOPE_H_ - -#include <InputScope.h> -#include <vector> - -#include "base/win/scoped_comptr.h" - -namespace metro_driver { - -// Returns an instance of ITfInputScope object, which represents an array of -// InputScope enumeration passed as |input_scopes|. -base::win::ScopedComPtr<ITfInputScope> -CreteInputScope(const std::vector<InputScope>& input_scopes); - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_TEXT_STORE_H_ diff --git a/win8/metro_driver/ime/input_source.cc b/win8/metro_driver/ime/input_source.cc deleted file mode 100644 index 079ddb0..0000000 --- a/win8/metro_driver/ime/input_source.cc +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2013 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/ime/input_source.h" - -#include <atlbase.h> -#include <atlcom.h> -#include <msctf.h> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/observer_list.h" -#include "base/win/scoped_comptr.h" -#include "ui/base/win/atl_module.h" -#include "win8/metro_driver/ime/input_source_observer.h" - -namespace metro_driver { -namespace { - -// An implementation of ITfLanguageProfileNotifySink interface, which will be -// used to receive notifications when the text input source is changed. -class ATL_NO_VTABLE InputSourceMonitor - : public CComObjectRootEx<CComMultiThreadModel>, - public ITfLanguageProfileNotifySink { - public: - InputSourceMonitor() - : cookie_(TF_INVALID_COOKIE) { - } - - BEGIN_COM_MAP(InputSourceMonitor) - COM_INTERFACE_ENTRY(ITfLanguageProfileNotifySink) - END_COM_MAP() - - bool Initialize(ITfSource* source) { - DWORD cookie = TF_INVALID_COOKIE; - HRESULT hr = source->AdviseSink(IID_ITfLanguageProfileNotifySink, - this, - &cookie); - if (FAILED(hr)) { - LOG(ERROR) << "ITfSource::AdviseSink failed. hr = " << hr; - return false; - } - cookie_ = cookie; - source_ = source; - return true; - } - - void SetCallback(base::Closure on_language_chanaged) { - on_language_chanaged_ = on_language_chanaged; - } - - void Unadvise() { - if (cookie_ == TF_INVALID_COOKIE || !source_.get()) - return; - if (FAILED(source_->UnadviseSink(cookie_))) - return; - cookie_ = TF_INVALID_COOKIE; - source_.Release(); - } - - private: - // ITfLanguageProfileNotifySink overrides: - STDMETHOD(OnLanguageChange)(LANGID langid, BOOL *accept) override { - if (!accept) - return E_INVALIDARG; - *accept = TRUE; - return S_OK; - } - - STDMETHOD(OnLanguageChanged)() override { - if (!on_language_chanaged_.is_null()) - on_language_chanaged_.Run(); - return S_OK; - } - - base::Closure on_language_chanaged_; - base::win::ScopedComPtr<ITfSource> source_; - DWORD cookie_; - - DISALLOW_COPY_AND_ASSIGN(InputSourceMonitor); -}; - -class InputSourceImpl : public InputSource { - public: - InputSourceImpl(ITfInputProcessorProfileMgr* profile_manager, - InputSourceMonitor* monitor) - : profile_manager_(profile_manager), - monitor_(monitor) { - monitor_->SetCallback(base::Bind(&InputSourceImpl::OnLanguageChanged, - base::Unretained(this))); - } - ~InputSourceImpl() override { - monitor_->SetCallback(base::Closure()); - monitor_->Unadvise(); - } - - private: - // InputSource overrides. - bool GetActiveSource(LANGID* langid, bool* is_ime) override { - TF_INPUTPROCESSORPROFILE profile = {}; - HRESULT hr = profile_manager_->GetActiveProfile(GUID_TFCAT_TIP_KEYBOARD, - &profile); - if (FAILED(hr)) { - LOG(ERROR) << "ITfInputProcessorProfileMgr::GetActiveProfile failed." - << " hr = " << hr; - return false; - } - *langid = profile.langid; - *is_ime = profile.dwProfileType == TF_PROFILETYPE_INPUTPROCESSOR; - return true; - } - void AddObserver(InputSourceObserver* observer) override { - observer_list_.AddObserver(observer); - } - void RemoveObserver(InputSourceObserver* observer) override { - observer_list_.RemoveObserver(observer); - } - void OnLanguageChanged() { - FOR_EACH_OBSERVER(InputSourceObserver, - observer_list_, - OnInputSourceChanged()); - } - - base::win::ScopedComPtr<ITfInputProcessorProfileMgr> profile_manager_; - scoped_refptr<InputSourceMonitor> monitor_; - base::ObserverList<InputSourceObserver> observer_list_; - - DISALLOW_COPY_AND_ASSIGN(InputSourceImpl); -}; - -} // namespace - -// static -scoped_ptr<InputSource> InputSource::Create() { - ui::win::CreateATLModuleIfNeeded(); - - base::win::ScopedComPtr<ITfInputProcessorProfileMgr> profile_manager; - HRESULT hr = profile_manager.CreateInstance(CLSID_TF_InputProcessorProfiles); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to instantiate CLSID_TF_InputProcessorProfiles." - << " hr = " << hr; - return scoped_ptr<InputSource>(); - } - base::win::ScopedComPtr<ITfSource> profiles_source; - hr = profiles_source.QueryFrom(profile_manager.get()); - if (FAILED(hr)) { - LOG(ERROR) << "QueryFrom to ITfSource failed. hr = " << hr; - return scoped_ptr<InputSource>(); - } - - CComObject<InputSourceMonitor>* monitor = NULL; - hr = CComObject<InputSourceMonitor>::CreateInstance(&monitor); - if (FAILED(hr)) { - LOG(ERROR) << "CComObject<InputSourceMonitor>::CreateInstance failed." - << " hr = " << hr; - return scoped_ptr<InputSource>(); - } - if (!monitor->Initialize(profiles_source.get())) { - LOG(ERROR) << "Failed to initialize the monitor."; - return scoped_ptr<InputSource>(); - } - - // Transfer the ownership. - return scoped_ptr<InputSource>( - new InputSourceImpl(profile_manager.get(), monitor)); -} - -} // namespace metro_driver diff --git a/win8/metro_driver/ime/input_source.h b/win8/metro_driver/ime/input_source.h deleted file mode 100644 index 8b057b2..0000000 --- a/win8/metro_driver/ime/input_source.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 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_IME_INPUT_SOURCE_H_ -#define WIN8_METRO_DRIVER_IME_INPUT_SOURCE_H_ - -#include <Windows.h> - -#include "base/memory/scoped_ptr.h" - -namespace metro_driver { - -class InputSourceObserver; - -// An interface through which information about the input source can be -// retrieved, where an input source represents an IME or a keyboard layout. -class InputSource { - public: - virtual ~InputSource() {} - // Create an instance. Returns NULL if fails. - static scoped_ptr<InputSource> Create(); - - // Returns true if |langid| and |is_ime| are filled based on the current - // active input source. - virtual bool GetActiveSource(LANGID* langid, bool* is_ime) = 0; - - // Adds/Removes an observer to receive notifications when the active input - // source is changed. - virtual void AddObserver(InputSourceObserver* observer) = 0; - virtual void RemoveObserver(InputSourceObserver* observer) = 0; -}; - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_INPUT_SOURCE_H_ diff --git a/win8/metro_driver/ime/input_source_observer.h b/win8/metro_driver/ime/input_source_observer.h deleted file mode 100644 index 196f33f..0000000 --- a/win8/metro_driver/ime/input_source_observer.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 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_IME_INPUT_SOURCE_OBSERVER_H_ -#define WIN8_METRO_DRIVER_IME_INPUT_SOURCE_OBSERVER_H_ - -#include <Windows.h> - - -namespace metro_driver { - -// An observer interface implemented by objects that want to be informed -// when the active language profile is changed. -class InputSourceObserver { - public: - virtual ~InputSourceObserver() {} - - // Called when the active language profile is changed. - virtual void OnInputSourceChanged() = 0; -}; - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_INPUT_SOURCE_OBSERVER_H_ diff --git a/win8/metro_driver/ime/text_service.cc b/win8/metro_driver/ime/text_service.cc deleted file mode 100644 index 1ee845e..0000000 --- a/win8/metro_driver/ime/text_service.cc +++ /dev/null @@ -1,490 +0,0 @@ -// Copyright 2013 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/ime/text_service.h" - -#include <msctf.h> -#include <stddef.h> -#include <stdint.h> - -#include <utility> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/win/scoped_variant.h" -#include "ui/metro_viewer/ime_types.h" -#include "win8/metro_driver/ime/text_service_delegate.h" -#include "win8/metro_driver/ime/text_store.h" -#include "win8/metro_driver/ime/text_store_delegate.h" - -// Architecture overview of input method support on Ash mode: -// -// Overview: -// On Ash mode, the system keyboard focus is owned by the metro_driver process -// while most of event handling are still implemented in the browser process. -// Thus the metro_driver basically works as a proxy that simply forwards -// keyevents to the metro_driver process. IME support must be involved somewhere -// in this flow. -// -// In short, we need to interact with an IME in the metro_driver process since -// TSF (Text Services Framework) runtime wants to processes keyevents while -// (and only while) the attached UI thread owns keyboard focus. -// -// Due to this limitation, we need to split IME handling into two parts, one -// is in the metro_driver process and the other is in the browser process. -// The metro_driver process is responsible for implementing the primary data -// store for the composition text and wiring it up with an IME via TSF APIs. -// On the other hand, the browser process is responsible for calculating -// character position in the composition text whenever the composition text -// is updated. -// -// IPC overview: -// Fortunately, we don't need so many IPC messages to support IMEs. In fact, -// only 4 messages are required to enable basic IME functionality. -// -// metro_driver process -> browser process -// Message Type: -// - MetroViewerHostMsg_ImeCompositionChanged -// - MetroViewerHostMsg_ImeTextCommitted -// Message Routing: -// TextServiceImpl -// -> ChromeAppViewAsh -// -- (process boundary) -- -// -> RemoteWindowTreeHostWin -// -> RemoteInputMethodWin -// -// browser process -> metro_driver process -// Message Type: -// - MetroViewerHostMsg_ImeCancelComposition -// - MetroViewerHostMsg_ImeTextInputClientUpdated -// Message Routing: -// RemoteInputMethodWin -// -> RemoteWindowTreeHostWin -// -- (process boundary) -- -// -> ChromeAppViewAsh -// -> TextServiceImpl -// -// Note that a keyevent may be forwarded through a different path. When a -// keyevent is not handled by an IME, such keyevent and subsequent character -// events will be sent from the metro_driver process to the browser process as -// following IPC messages. -// - MetroViewerHostMsg_KeyDown -// - MetroViewerHostMsg_KeyUp -// - MetroViewerHostMsg_Character -// -// How TextServiceImpl works: -// Here is the list of the major tasks that are handled in TextServiceImpl. -// - Manages a session object obtained from TSF runtime. We need them to call -// most of TSF APIs. -// - Handles OnDocumentChanged event. Whenever the document type is changed, -// TextServiceImpl destroyes the current document and initializes new one -// according to the given |input_scopes|. -// - Stores the |composition_character_bounds_| passed from OnDocumentChanged -// event so that an IME or on-screen keyboard can query the character -// position synchronously. -// The most complicated part is the OnDocumentChanged handler. Since some IMEs -// such as Japanese IMEs drastically change their behavior depending on -// properties exposed from the virtual document, we need to set up a lot -// properties carefully and correctly. See DocumentBinding class in this file -// about what will be involved in this multi-phase construction. See also -// text_store.cc and input_scope.cc for more underlying details. - -namespace metro_driver { -namespace { - -// Japanese IME expects the default value of this compartment is -// TF_SENTENCEMODE_PHRASEPREDICT to emulate IMM32 behavior. This value is -// managed per thread, thus setting this value at once is sufficient. This -// value never affects non-Japanese IMEs. -bool InitializeSentenceMode(ITfThreadMgr* thread_manager, - TfClientId client_id) { - base::win::ScopedComPtr<ITfCompartmentMgr> thread_compartment_manager; - HRESULT hr = thread_compartment_manager.QueryFrom(thread_manager); - if (FAILED(hr)) { - LOG(ERROR) << "QueryFrom failed. hr = " << hr; - return false; - } - base::win::ScopedComPtr<ITfCompartment> sentence_compartment; - hr = thread_compartment_manager->GetCompartment( - GUID_COMPARTMENT_KEYBOARD_INPUTMODE_SENTENCE, - sentence_compartment.Receive()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfCompartment::GetCompartment failed. hr = " << hr; - return false; - } - - base::win::ScopedVariant sentence_variant; - sentence_variant.Set(TF_SENTENCEMODE_PHRASEPREDICT); - hr = sentence_compartment->SetValue(client_id, sentence_variant.ptr()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfCompartment::SetValue failed. hr = " << hr; - return false; - } - return true; -} - -// Initializes |context| as disabled context where IMEs will be disabled. -bool InitializeDisabledContext(ITfContext* context, TfClientId client_id) { - base::win::ScopedComPtr<ITfCompartmentMgr> compartment_mgr; - HRESULT hr = compartment_mgr.QueryFrom(context); - if (FAILED(hr)) { - LOG(ERROR) << "QueryFrom failed. hr = " << hr; - return false; - } - - base::win::ScopedComPtr<ITfCompartment> disabled_compartment; - hr = compartment_mgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_DISABLED, - disabled_compartment.Receive()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfCompartment::GetCompartment failed. hr = " << hr; - return false; - } - - base::win::ScopedVariant variant; - variant.Set(1); - hr = disabled_compartment->SetValue(client_id, variant.ptr()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfCompartment::SetValue failed. hr = " << hr; - return false; - } - - base::win::ScopedComPtr<ITfCompartment> empty_context; - hr = compartment_mgr->GetCompartment(GUID_COMPARTMENT_EMPTYCONTEXT, - empty_context.Receive()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfCompartment::GetCompartment failed. hr = " << hr; - return false; - } - - base::win::ScopedVariant empty_context_variant; - empty_context_variant.Set(static_cast<int32_t>(1)); - hr = empty_context->SetValue(client_id, empty_context_variant.ptr()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfCompartment::SetValue failed. hr = " << hr; - return false; - } - - return true; -} - -bool IsPasswordField(const std::vector<InputScope>& input_scopes) { - return std::find(input_scopes.begin(), input_scopes.end(), IS_PASSWORD) != - input_scopes.end(); -} - -// A class that manages the lifetime of the event callback registration. When -// this object is destroyed, corresponding event callback will be unregistered. -class EventSink { - public: - EventSink(DWORD cookie, base::win::ScopedComPtr<ITfSource> source) - : cookie_(cookie), - source_(source) {} - ~EventSink() { - if (!source_.get() || cookie_ != TF_INVALID_COOKIE) - return; - source_->UnadviseSink(cookie_); - cookie_ = TF_INVALID_COOKIE; - source_.Release(); - } - - private: - DWORD cookie_; - base::win::ScopedComPtr<ITfSource> source_; - DISALLOW_COPY_AND_ASSIGN(EventSink); -}; - -scoped_ptr<EventSink> CreateTextEditSink(ITfContext* context, - ITfTextEditSink* text_store) { - DCHECK(text_store); - base::win::ScopedComPtr<ITfSource> source; - DWORD cookie = TF_INVALID_EDIT_COOKIE; - HRESULT hr = source.QueryFrom(context); - if (FAILED(hr)) { - LOG(ERROR) << "QueryFrom failed, hr = " << hr; - return scoped_ptr<EventSink>(); - } - hr = source->AdviseSink(IID_ITfTextEditSink, text_store, &cookie); - if (FAILED(hr)) { - LOG(ERROR) << "AdviseSink failed, hr = " << hr; - return scoped_ptr<EventSink>(); - } - return scoped_ptr<EventSink>(new EventSink(cookie, source)); -} - -// A set of objects that should have the same lifetime. Following things -// are maintained. -// - TextStore: a COM object that abstracts text buffer. This object is -// actually implemented by us in text_store.cc -// - ITfDocumentMgr: a focusable unit in TSF. This object is implemented by -// TSF runtime and works as a container of TextStore. -// - EventSink: an object that ensures that the event callback between -// TSF runtime and TextStore is unregistered when this object is destroyed. -class DocumentBinding { - public: - ~DocumentBinding() { - if (!document_manager_.get()) - return; - document_manager_->Pop(TF_POPF_ALL); - } - - static scoped_ptr<DocumentBinding> Create( - ITfThreadMgr* thread_manager, - TfClientId client_id, - const std::vector<InputScope>& input_scopes, - HWND window_handle, - TextStoreDelegate* delegate) { - base::win::ScopedComPtr<ITfDocumentMgr> document_manager; - HRESULT hr = thread_manager->CreateDocumentMgr(document_manager.Receive()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfThreadMgr::CreateDocumentMgr failed. hr = " << hr; - return scoped_ptr<DocumentBinding>(); - } - - // Note: In our IPC protocol, an empty |input_scopes| is used to indicate - // that an IME must be disabled in this context. In such case, we need not - // instantiate TextStore. - const bool use_null_text_store = input_scopes.empty(); - - scoped_refptr<TextStore> text_store; - if (!use_null_text_store) { - text_store = TextStore::Create(window_handle, input_scopes, delegate); - if (!text_store.get()) { - LOG(ERROR) << "Failed to create TextStore."; - return scoped_ptr<DocumentBinding>(); - } - } - - base::win::ScopedComPtr<ITfContext> context; - DWORD edit_cookie = TF_INVALID_EDIT_COOKIE; - hr = document_manager->CreateContext( - client_id, - 0, - static_cast<ITextStoreACP*>(text_store.get()), - context.Receive(), - &edit_cookie); - if (FAILED(hr)) { - LOG(ERROR) << "ITfDocumentMgr::CreateContext failed. hr = " << hr; - return scoped_ptr<DocumentBinding>(); - } - - // If null-TextStore is used or |input_scopes| looks like a password field, - // set special properties to tell IMEs to be disabled. - if ((use_null_text_store || IsPasswordField(input_scopes)) && - !InitializeDisabledContext(context.get(), client_id)) { - LOG(ERROR) << "InitializeDisabledContext failed."; - return scoped_ptr<DocumentBinding>(); - } - - scoped_ptr<EventSink> text_edit_sink; - if (!use_null_text_store) { - text_edit_sink = CreateTextEditSink(context.get(), text_store.get()); - if (!text_edit_sink) { - LOG(ERROR) << "CreateTextEditSink failed."; - return scoped_ptr<DocumentBinding>(); - } - } - hr = document_manager->Push(context.get()); - if (FAILED(hr)) { - LOG(ERROR) << "ITfDocumentMgr::Push failed. hr = " << hr; - return scoped_ptr<DocumentBinding>(); - } - return scoped_ptr<DocumentBinding>(new DocumentBinding( - text_store, document_manager, std::move(text_edit_sink))); - } - - ITfDocumentMgr* document_manager() const { return document_manager_.get(); } - - scoped_refptr<TextStore> text_store() const { - return text_store_; - } - - private: - DocumentBinding(scoped_refptr<TextStore> text_store, - base::win::ScopedComPtr<ITfDocumentMgr> document_manager, - scoped_ptr<EventSink> text_edit_sink) - : text_store_(text_store), - document_manager_(document_manager), - text_edit_sink_(std::move(text_edit_sink)) {} - - scoped_refptr<TextStore> text_store_; - base::win::ScopedComPtr<ITfDocumentMgr> document_manager_; - scoped_ptr<EventSink> text_edit_sink_; - - DISALLOW_COPY_AND_ASSIGN(DocumentBinding); -}; - -class TextServiceImpl : public TextService, - public TextStoreDelegate { - public: - TextServiceImpl(ITfThreadMgr* thread_manager, - TfClientId client_id, - HWND window_handle, - TextServiceDelegate* delegate) - : client_id_(client_id), - window_handle_(window_handle), - delegate_(delegate), - thread_manager_(thread_manager) { - DCHECK_NE(TF_CLIENTID_NULL, client_id); - DCHECK(window_handle != NULL); - DCHECK(thread_manager_.get()); - } - ~TextServiceImpl() override { - thread_manager_->Deactivate(); - } - - private: - // TextService overrides: - void CancelComposition() override { - if (!current_document_) { - VLOG(0) << "|current_document_| is NULL due to the previous error."; - return; - } - scoped_refptr<TextStore> text_store = current_document_->text_store(); - if (!text_store.get()) - return; - text_store->CancelComposition(); - } - - void OnDocumentChanged(const std::vector<int32_t>& input_scopes, - const std::vector<metro_viewer::CharacterBounds>& - character_bounds) override { - bool document_type_changed = input_scopes_ != input_scopes; - input_scopes_ = input_scopes; - composition_character_bounds_ = character_bounds; - if (document_type_changed) - OnDocumentTypeChanged(input_scopes); - } - - void OnWindowActivated() override { - if (!current_document_) { - VLOG(0) << "|current_document_| is NULL due to the previous error."; - return; - } - ITfDocumentMgr* document_manager = current_document_->document_manager(); - if (!document_manager) { - VLOG(0) << "|document_manager| is NULL due to the previous error."; - return; - } - HRESULT hr = thread_manager_->SetFocus(document_manager); - if (FAILED(hr)) { - LOG(ERROR) << "ITfThreadMgr::SetFocus failed. hr = " << hr; - return; - } - } - - void OnCompositionChanged( - const base::string16& text, - int32_t selection_start, - int32_t selection_end, - const std::vector<metro_viewer::UnderlineInfo>& underlines) override { - if (!delegate_) - return; - delegate_->OnCompositionChanged(text, - selection_start, - selection_end, - underlines); - } - - void OnTextCommitted(const base::string16& text) override { - if (!delegate_) - return; - delegate_->OnTextCommitted(text); - } - - RECT GetCaretBounds() override { - if (composition_character_bounds_.empty()) { - const RECT rect = {}; - return rect; - } - const metro_viewer::CharacterBounds& bounds = - composition_character_bounds_[0]; - POINT left_top = { bounds.left, bounds.top }; - POINT right_bottom = { bounds.right, bounds.bottom }; - ClientToScreen(window_handle_, &left_top); - ClientToScreen(window_handle_, &right_bottom); - const RECT rect = { - left_top.x, - left_top.y, - right_bottom.x, - right_bottom.y, - }; - return rect; - } - - bool GetCompositionCharacterBounds(uint32_t index, RECT* rect) override { - if (index >= composition_character_bounds_.size()) { - return false; - } - const metro_viewer::CharacterBounds& bounds = - composition_character_bounds_[index]; - POINT left_top = { bounds.left, bounds.top }; - POINT right_bottom = { bounds.right, bounds.bottom }; - ClientToScreen(window_handle_, &left_top); - ClientToScreen(window_handle_, &right_bottom); - SetRect(rect, left_top.x, left_top.y, right_bottom.x, right_bottom.y); - return true; - } - - void OnDocumentTypeChanged(const std::vector<int32_t>& input_scopes) { - std::vector<InputScope> native_input_scopes(input_scopes.size()); - for (size_t i = 0; i < input_scopes.size(); ++i) - native_input_scopes[i] = static_cast<InputScope>(input_scopes[i]); - scoped_ptr<DocumentBinding> new_document = - DocumentBinding::Create(thread_manager_.get(), - client_id_, - native_input_scopes, - window_handle_, - this); - LOG_IF(ERROR, !new_document) << "Failed to create a new document."; - current_document_.swap(new_document); - OnWindowActivated(); - } - - TfClientId client_id_; - HWND window_handle_; - TextServiceDelegate* delegate_; - scoped_ptr<DocumentBinding> current_document_; - base::win::ScopedComPtr<ITfThreadMgr> thread_manager_; - - // A vector of InputScope enumeration, which represents the document type of - // the focused text field. Note that in our IPC message protocol, an empty - // |input_scopes_| has special meaning that IMEs must be disabled on this - // document. - std::vector<int32_t> input_scopes_; - // Character bounds of the composition. When there is no composition but this - // vector is not empty, the first element contains the caret bounds. - std::vector<metro_viewer::CharacterBounds> composition_character_bounds_; - - DISALLOW_COPY_AND_ASSIGN(TextServiceImpl); -}; - -} // namespace - -scoped_ptr<TextService> -CreateTextService(TextServiceDelegate* delegate, HWND window_handle) { - if (!delegate) - return scoped_ptr<TextService>(); - base::win::ScopedComPtr<ITfThreadMgr> thread_manager; - HRESULT hr = thread_manager.CreateInstance(CLSID_TF_ThreadMgr); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create instance of CLSID_TF_ThreadMgr. hr = " - << hr; - return scoped_ptr<TextService>(); - } - TfClientId client_id = TF_CLIENTID_NULL; - hr = thread_manager->Activate(&client_id); - if (FAILED(hr)) { - LOG(ERROR) << "ITfThreadMgr::Activate failed. hr = " << hr; - return scoped_ptr<TextService>(); - } - if (!InitializeSentenceMode(thread_manager.get(), client_id)) { - LOG(ERROR) << "InitializeSentenceMode failed."; - thread_manager->Deactivate(); - return scoped_ptr<TextService>(); - } - return scoped_ptr<TextService>(new TextServiceImpl( - thread_manager.get(), client_id, window_handle, delegate)); -} - -} // namespace metro_driver diff --git a/win8/metro_driver/ime/text_service.h b/win8/metro_driver/ime/text_service.h deleted file mode 100644 index c3dcacd..0000000 --- a/win8/metro_driver/ime/text_service.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2013 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_IME_TEXT_SERVICE_H_ -#define WIN8_METRO_DRIVER_IME_TEXT_SERVICE_H_ - -#include <windows.h> -#include <stdint.h> - -#include <vector> - -#include "base/memory/scoped_ptr.h" - -namespace metro_viewer { -struct CharacterBounds; -} - -namespace metro_driver { - -class TextServiceDelegate; - -// An interface to manage a virtual text store with which an IME communicates. -class TextService { - public: - virtual ~TextService() {} - - // Cancels on-going composition. Does nothing if there is no composition. - virtual void CancelComposition() = 0; - - // Updates document type with |input_scopes| and caret/composition position - // with |character_bounds|. An empty |input_scopes| indicates that IMEs - // should be disabled until non-empty |input_scopes| is specified. - // Note: |input_scopes| is defined as std::vector<int32_t> here rather than - // std::vector<InputScope> because the wire format of IPC message - // MetroViewerHostMsg_ImeTextInputClientUpdated uses std::vector<int32_t> to - // avoid dependency on <InputScope.h> header. - virtual void OnDocumentChanged( - const std::vector<int32_t>& input_scopes, - const std::vector<metro_viewer::CharacterBounds>& character_bounds) = 0; - - // Must be called whenever the attached window gains keyboard focus. - virtual void OnWindowActivated() = 0; -}; - -// Returns an instance of TextService that works together with -// |text_store_delegate| as if it was an text area owned by |window_handle|. -scoped_ptr<TextService> -CreateTextService(TextServiceDelegate* delegate, HWND window_handle); - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_TEXT_SERVICE_H_ diff --git a/win8/metro_driver/ime/text_service_delegate.h b/win8/metro_driver/ime/text_service_delegate.h deleted file mode 100644 index b78bec0..0000000 --- a/win8/metro_driver/ime/text_service_delegate.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2013 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_IME_TEXT_SERVICE_DELEGATE_H_ -#define WIN8_METRO_DRIVER_IME_TEXT_SERVICE_DELEGATE_H_ - -#include <stdint.h> - -#include <vector> - -#include "base/strings/string16.h" - -namespace metro_viewer { -struct UnderlineInfo; -} - -namespace metro_driver { - -// A delegate which works together with virtual text service. -// Objects that implement this delegate will receive notifications from a -// virtual text service whenever an IME updates the composition or commits text. -class TextServiceDelegate { - public: - virtual ~TextServiceDelegate() {} - - // Called when on-going composition is updated. An empty |text| represents - // that the composition is canceled. - virtual void OnCompositionChanged( - const base::string16& text, - int32_t selection_start, - int32_t selection_end, - const std::vector<metro_viewer::UnderlineInfo>& underlines) = 0; - - // Called when |text| is committed. - virtual void OnTextCommitted(const base::string16& text) = 0; -}; - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_TEXT_SERVICE_DELEGATE_H_ diff --git a/win8/metro_driver/ime/text_store.cc b/win8/metro_driver/ime/text_store.cc deleted file mode 100644 index 0b3c9fa..0000000 --- a/win8/metro_driver/ime/text_store.cc +++ /dev/null @@ -1,897 +0,0 @@ -// Copyright 2013 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/ime/text_store.h" - -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> - -#include "base/win/scoped_variant.h" -#include "ui/base/win/atl_module.h" -#include "win8/metro_driver/ime/input_scope.h" -#include "win8/metro_driver/ime/text_store_delegate.h" - -namespace metro_driver { -namespace { - -// We support only one view. -const TsViewCookie kViewCookie = 1; - -} // namespace - -TextStore::TextStore() - : text_store_acp_sink_mask_(0), - window_handle_(NULL), - committed_size_(0), - selection_start_(0), - selection_end_(0), - edit_flag_(false), - current_lock_type_(0), - category_manager_(NULL), - display_attribute_manager_(NULL), - input_scope_(NULL), - delegate_(NULL) { -} - -TextStore::~TextStore() { -} - -// static -scoped_refptr<TextStore> TextStore::Create( - HWND window_handle, - const std::vector<InputScope>& input_scopes, - TextStoreDelegate* delegate) { - if (!delegate) { - LOG(ERROR) << "|delegate| must be non-NULL."; - return scoped_refptr<TextStore>(); - } - base::win::ScopedComPtr<ITfCategoryMgr> category_manager; - HRESULT hr = category_manager.CreateInstance(CLSID_TF_CategoryMgr); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to initialize CategoryMgr. hr = " << hr; - return scoped_refptr<TextStore>(); - } - base::win::ScopedComPtr<ITfDisplayAttributeMgr> display_attribute_manager; - hr = display_attribute_manager.CreateInstance(CLSID_TF_DisplayAttributeMgr); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to initialize DisplayAttributeMgr. hr = " << hr; - return scoped_refptr<TextStore>(); - } - base::win::ScopedComPtr<ITfInputScope> input_scope = - CreteInputScope(input_scopes); - if (!input_scope.get()) { - LOG(ERROR) << "Failed to initialize InputScope."; - return scoped_refptr<TextStore>(); - } - - ui::win::CreateATLModuleIfNeeded(); - CComObject<TextStore>* object = NULL; - hr = CComObject<TextStore>::CreateInstance(&object); - if (FAILED(hr)) { - LOG(ERROR) << "CComObject<TextStore>::CreateInstance failed. hr = " - << hr; - return scoped_refptr<TextStore>(); - } - object->Initialize(window_handle, category_manager.get(), - display_attribute_manager.get(), input_scope.get(), - delegate); - return scoped_refptr<TextStore>(object); -} - -void TextStore::Initialize(HWND window_handle, - ITfCategoryMgr* category_manager, - ITfDisplayAttributeMgr* display_attribute_manager, - ITfInputScope* input_scope, - TextStoreDelegate* delegate) { - window_handle_ = window_handle; - category_manager_ = category_manager; - display_attribute_manager_ = display_attribute_manager; - input_scope_ = input_scope; - delegate_ = delegate; -} - - -STDMETHODIMP TextStore::AdviseSink(REFIID iid, - IUnknown* unknown, - DWORD mask) { - if (!IsEqualGUID(iid, IID_ITextStoreACPSink)) - return E_INVALIDARG; - if (text_store_acp_sink_.get()) { - if (text_store_acp_sink_.IsSameObject(unknown)) { - text_store_acp_sink_mask_ = mask; - return S_OK; - } else { - return CONNECT_E_ADVISELIMIT; - } - } - if (FAILED(text_store_acp_sink_.QueryFrom(unknown))) - return E_UNEXPECTED; - text_store_acp_sink_mask_ = mask; - - return S_OK; -} - -STDMETHODIMP TextStore::FindNextAttrTransition( - LONG acp_start, - LONG acp_halt, - ULONG num_filter_attributes, - const TS_ATTRID* filter_attributes, - DWORD flags, - LONG* acp_next, - BOOL* found, - LONG* found_offset) { - if (!acp_next || !found || !found_offset) - return E_INVALIDARG; - // We don't support any attributes. - // So we always return "not found". - *acp_next = 0; - *found = FALSE; - *found_offset = 0; - return S_OK; -} - -STDMETHODIMP TextStore::GetACPFromPoint(TsViewCookie view_cookie, - const POINT* point, - DWORD flags, - LONG* acp) { - NOTIMPLEMENTED(); - if (view_cookie != kViewCookie) - return E_INVALIDARG; - return E_NOTIMPL; -} - -STDMETHODIMP TextStore::GetActiveView(TsViewCookie* view_cookie) { - if (!view_cookie) - return E_INVALIDARG; - // We support only one view. - *view_cookie = kViewCookie; - return S_OK; -} - -STDMETHODIMP TextStore::GetEmbedded(LONG acp_pos, - REFGUID service, - REFIID iid, - IUnknown** unknown) { - // We don't support any embedded objects. - NOTIMPLEMENTED(); - if (!unknown) - return E_INVALIDARG; - *unknown = NULL; - return E_NOTIMPL; -} - -STDMETHODIMP TextStore::GetEndACP(LONG* acp) { - if (!acp) - return E_INVALIDARG; - if (!HasReadLock()) - return TS_E_NOLOCK; - *acp = static_cast<LONG>(string_buffer_.size()); - return S_OK; -} - -STDMETHODIMP TextStore::GetFormattedText(LONG acp_start, - LONG acp_end, - IDataObject** data_object) { - NOTIMPLEMENTED(); - return E_NOTIMPL; -} - -STDMETHODIMP TextStore::GetScreenExt(TsViewCookie view_cookie, RECT* rect) { - if (view_cookie != kViewCookie) - return E_INVALIDARG; - if (!rect) - return E_INVALIDARG; - - // {0, 0, 0, 0} means that the document rect is not currently displayed. - SetRect(rect, 0, 0, 0, 0); - - RECT client_rect = {}; - if (!GetClientRect(window_handle_, &client_rect)) - return E_FAIL; - POINT left_top = {client_rect.left, client_rect.top}; - POINT right_bottom = {client_rect.right, client_rect.bottom}; - if (!ClientToScreen(window_handle_, &left_top)) - return E_FAIL; - if (!ClientToScreen(window_handle_, &right_bottom)) - return E_FAIL; - - rect->left = left_top.x; - rect->top = left_top.y; - rect->right = right_bottom.x; - rect->bottom = right_bottom.y; - return S_OK; -} - -STDMETHODIMP TextStore::GetSelection(ULONG selection_index, - ULONG selection_buffer_size, - TS_SELECTION_ACP* selection_buffer, - ULONG* fetched_count) { - if (!selection_buffer) - return E_INVALIDARG; - if (!fetched_count) - return E_INVALIDARG; - if (!HasReadLock()) - return TS_E_NOLOCK; - *fetched_count = 0; - if ((selection_buffer_size > 0) && - ((selection_index == 0) || (selection_index == TS_DEFAULT_SELECTION))) { - selection_buffer[0].acpStart = selection_start_; - selection_buffer[0].acpEnd = selection_end_; - selection_buffer[0].style.ase = TS_AE_END; - selection_buffer[0].style.fInterimChar = FALSE; - *fetched_count = 1; - } - return S_OK; -} - -STDMETHODIMP TextStore::GetStatus(TS_STATUS* status) { - if (!status) - return E_INVALIDARG; - - status->dwDynamicFlags = 0; - // We use transitory contexts and we don't support hidden text. - status->dwStaticFlags = TS_SS_TRANSITORY | TS_SS_NOHIDDENTEXT; - - return S_OK; -} - -STDMETHODIMP TextStore::GetText(LONG acp_start, - LONG acp_end, - wchar_t* text_buffer, - ULONG text_buffer_size, - ULONG* text_buffer_copied, - TS_RUNINFO* run_info_buffer, - ULONG run_info_buffer_size, - ULONG* run_info_buffer_copied, - LONG* next_acp) { - if (!text_buffer_copied || !run_info_buffer_copied) - return E_INVALIDARG; - if (!text_buffer && text_buffer_size != 0) - return E_INVALIDARG; - if (!run_info_buffer && run_info_buffer_size != 0) - return E_INVALIDARG; - if (!next_acp) - return E_INVALIDARG; - if (!HasReadLock()) - return TF_E_NOLOCK; - const LONG string_buffer_size = static_cast<LONG>(string_buffer_.size()); - if (acp_end == -1) - acp_end = string_buffer_size; - if (!((0 <= acp_start) && - (acp_start <= acp_end) && - (acp_end <= string_buffer_size))) { - return TF_E_INVALIDPOS; - } - acp_end = std::min(acp_end, acp_start + static_cast<LONG>(text_buffer_size)); - *text_buffer_copied = acp_end - acp_start; - - const base::string16& result = - string_buffer_.substr(acp_start, *text_buffer_copied); - for (size_t i = 0; i < result.size(); ++i) - text_buffer[i] = result[i]; - - if (run_info_buffer_size) { - run_info_buffer[0].uCount = *text_buffer_copied; - run_info_buffer[0].type = TS_RT_PLAIN; - *run_info_buffer_copied = 1; - } - - *next_acp = acp_end; - return S_OK; -} - -STDMETHODIMP TextStore::GetTextExt(TsViewCookie view_cookie, - LONG acp_start, - LONG acp_end, - RECT* rect, - BOOL* clipped) { - if (!rect || !clipped) - return E_INVALIDARG; - if (view_cookie != kViewCookie) - return E_INVALIDARG; - if (!HasReadLock()) - return TS_E_NOLOCK; - if (!((static_cast<LONG>(committed_size_) <= acp_start) && - (acp_start <= acp_end) && - (acp_end <= static_cast<LONG>(string_buffer_.size())))) { - return TS_E_INVALIDPOS; - } - - // According to a behavior of notepad.exe and wordpad.exe, top left corner of - // rect indicates a first character's one, and bottom right corner of rect - // indicates a last character's one. - // We use RECT instead of gfx::Rect since left position may be bigger than - // right position when composition has multiple lines. - RECT result; - RECT tmp_rect; - const uint32_t start_pos = acp_start - committed_size_; - const uint32_t end_pos = acp_end - committed_size_; - - if (start_pos == end_pos) { - // According to MSDN document, if |acp_start| and |acp_end| are equal it is - // OK to just return E_INVALIDARG. - // http://msdn.microsoft.com/en-us/library/ms538435 - // But when using Pinin IME of Windows 8, this method is called with the - // equal values of |acp_start| and |acp_end|. So we handle this condition. - if (start_pos == 0) { - if (delegate_->GetCompositionCharacterBounds(0, &tmp_rect)) { - tmp_rect.right = tmp_rect.right; - result = tmp_rect; - } else if (string_buffer_.size() == committed_size_) { - result = delegate_->GetCaretBounds(); - } else { - return TS_E_NOLAYOUT; - } - } else if (delegate_->GetCompositionCharacterBounds(start_pos - 1, - &tmp_rect)) { - tmp_rect.left = tmp_rect.right; - result = tmp_rect; - } else { - return TS_E_NOLAYOUT; - } - } else { - if (delegate_->GetCompositionCharacterBounds(start_pos, &tmp_rect)) { - result = tmp_rect; - if (delegate_->GetCompositionCharacterBounds(end_pos - 1, &tmp_rect)) { - result.right = tmp_rect.right; - result.bottom = tmp_rect.bottom; - } else { - // We may not be able to get the last character bounds, so we use the - // first character bounds instead of returning TS_E_NOLAYOUT. - } - } else { - // Hack for PPAPI flash. PPAPI flash does not support GetCaretBounds, so - // it's better to return previous caret rectangle instead. - // TODO(nona, kinaba): Remove this hack. - if (start_pos == 0) - result = delegate_->GetCaretBounds(); - else - return TS_E_NOLAYOUT; - } - } - - *rect = result; - *clipped = FALSE; - return S_OK; -} - -STDMETHODIMP TextStore::GetWnd(TsViewCookie view_cookie, - HWND* window_handle) { - if (!window_handle) - return E_INVALIDARG; - if (view_cookie != kViewCookie) - return E_INVALIDARG; - *window_handle = window_handle_; - return S_OK; -} - -STDMETHODIMP TextStore::InsertEmbedded(DWORD flags, - LONG acp_start, - LONG acp_end, - IDataObject* data_object, - TS_TEXTCHANGE* change) { - // We don't support any embedded objects. - NOTIMPLEMENTED(); - return E_NOTIMPL; -} - -STDMETHODIMP TextStore::InsertEmbeddedAtSelection(DWORD flags, - IDataObject* data_object, - LONG* acp_start, - LONG* acp_end, - TS_TEXTCHANGE* change) { - // We don't support any embedded objects. - NOTIMPLEMENTED(); - return E_NOTIMPL; -} - -STDMETHODIMP TextStore::InsertTextAtSelection(DWORD flags, - const wchar_t* text_buffer, - ULONG text_buffer_size, - LONG* acp_start, - LONG* acp_end, - TS_TEXTCHANGE* text_change) { - const LONG start_pos = selection_start_; - const LONG end_pos = selection_end_; - const LONG new_end_pos = start_pos + text_buffer_size; - - if (flags & TS_IAS_QUERYONLY) { - if (!HasReadLock()) - return TS_E_NOLOCK; - if (acp_start) - *acp_start = start_pos; - if (acp_end) - *acp_end = end_pos; - return S_OK; - } - - if (!HasReadWriteLock()) - return TS_E_NOLOCK; - if (!text_buffer) - return E_INVALIDARG; - - DCHECK_LE(start_pos, end_pos); - string_buffer_ = string_buffer_.substr(0, start_pos) + - base::string16(text_buffer, text_buffer + text_buffer_size) + - string_buffer_.substr(end_pos); - if (acp_start) - *acp_start = start_pos; - if (acp_end) - *acp_end = new_end_pos; - if (text_change) { - text_change->acpStart = start_pos; - text_change->acpOldEnd = end_pos; - text_change->acpNewEnd = new_end_pos; - } - selection_start_ = start_pos; - selection_end_ = new_end_pos; - return S_OK; -} - -STDMETHODIMP TextStore::QueryInsert( - LONG acp_test_start, - LONG acp_test_end, - ULONG text_size, - LONG* acp_result_start, - LONG* acp_result_end) { - if (!acp_result_start || !acp_result_end || acp_test_start > acp_test_end) - return E_INVALIDARG; - const LONG committed_size = static_cast<LONG>(committed_size_); - const LONG buffer_size = static_cast<LONG>(string_buffer_.size()); - *acp_result_start = std::min(std::max(committed_size, acp_test_start), - buffer_size); - *acp_result_end = std::min(std::max(committed_size, acp_test_end), - buffer_size); - return S_OK; -} - -STDMETHODIMP TextStore::QueryInsertEmbedded(const GUID* service, - const FORMATETC* format, - BOOL* insertable) { - if (!format) - return E_INVALIDARG; - // We don't support any embedded objects. - if (insertable) - *insertable = FALSE; - return S_OK; -} - -STDMETHODIMP TextStore::RequestAttrsAtPosition( - LONG acp_pos, - ULONG attribute_buffer_size, - const TS_ATTRID* attribute_buffer, - DWORD flags) { - // We don't support any document attributes. - // This method just returns S_OK, and the subsequently called - // RetrieveRequestedAttrs() returns 0 as the number of supported attributes. - return S_OK; -} - -STDMETHODIMP TextStore::RequestAttrsTransitioningAtPosition( - LONG acp_pos, - ULONG attribute_buffer_size, - const TS_ATTRID* attribute_buffer, - DWORD flags) { - // We don't support any document attributes. - // This method just returns S_OK, and the subsequently called - // RetrieveRequestedAttrs() returns 0 as the number of supported attributes. - return S_OK; -} - -STDMETHODIMP TextStore::RequestLock(DWORD lock_flags, HRESULT* result) { - if (!text_store_acp_sink_.get()) - return E_FAIL; - if (!result) - return E_INVALIDARG; - - if (current_lock_type_ != 0) { - if (lock_flags & TS_LF_SYNC) { - // Can't lock synchronously. - *result = TS_E_SYNCHRONOUS; - return S_OK; - } - // Queue the lock request. - lock_queue_.push_back(lock_flags & TS_LF_READWRITE); - *result = TS_S_ASYNC; - return S_OK; - } - - // Lock - current_lock_type_ = (lock_flags & TS_LF_READWRITE); - - edit_flag_ = false; - const uint32_t last_committed_size = committed_size_; - - // Grant the lock. - *result = text_store_acp_sink_->OnLockGranted(current_lock_type_); - - // Unlock - current_lock_type_ = 0; - - // Handles the pending lock requests. - while (!lock_queue_.empty()) { - current_lock_type_ = lock_queue_.front(); - lock_queue_.pop_front(); - text_store_acp_sink_->OnLockGranted(current_lock_type_); - current_lock_type_ = 0; - } - - if (!edit_flag_) - return S_OK; - - // If the text store is edited in OnLockGranted(), we may need to call - // TextStoreDelegate::ConfirmComposition() or - // TextStoreDelegate::SetComposition(). - const uint32_t new_committed_size = committed_size_; - const base::string16& new_committed_string = - string_buffer_.substr(last_committed_size, - new_committed_size - last_committed_size); - const base::string16& composition_string = - string_buffer_.substr(new_committed_size); - - // If there is new committed string, calls - // TextStoreDelegate::ConfirmComposition(). - if ((!new_committed_string.empty())) - delegate_->OnTextCommitted(new_committed_string); - - // Calls TextInputClient::SetCompositionText(). - std::vector<metro_viewer::UnderlineInfo> underlines = underlines_; - // Adjusts the offset. - for (size_t i = 0; i < underlines_.size(); ++i) { - underlines[i].start_offset -= new_committed_size; - underlines[i].end_offset -= new_committed_size; - } - int32_t selection_start = 0; - int32_t selection_end = 0; - if (selection_start_ >= new_committed_size) - selection_start = selection_start_ - new_committed_size; - if (selection_end_ >= new_committed_size) - selection_end = selection_end_ - new_committed_size; - delegate_->OnCompositionChanged( - composition_string, selection_start, selection_end, underlines); - - // If there is no composition string, clear the text store status. - // And call OnSelectionChange(), OnLayoutChange(), and OnTextChange(). - if ((composition_string.empty()) && (new_committed_size != 0)) { - string_buffer_.clear(); - committed_size_ = 0; - selection_start_ = 0; - selection_end_ = 0; - if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE) - text_store_acp_sink_->OnSelectionChange(); - if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE) - text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); - if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { - TS_TEXTCHANGE textChange; - textChange.acpStart = 0; - textChange.acpOldEnd = new_committed_size; - textChange.acpNewEnd = 0; - text_store_acp_sink_->OnTextChange(0, &textChange); - } - } - - return S_OK; -} - -STDMETHODIMP TextStore::RequestSupportedAttrs( - DWORD /* flags */, // Seems that we should ignore this. - ULONG attribute_buffer_size, - const TS_ATTRID* attribute_buffer) { - if (!attribute_buffer) - return E_INVALIDARG; - if (!input_scope_.get()) - return E_FAIL; - // We support only input scope attribute. - for (size_t i = 0; i < attribute_buffer_size; ++i) { - if (IsEqualGUID(GUID_PROP_INPUTSCOPE, attribute_buffer[i])) - return S_OK; - } - return E_FAIL; -} - -STDMETHODIMP TextStore::RetrieveRequestedAttrs( - ULONG attribute_buffer_size, - TS_ATTRVAL* attribute_buffer, - ULONG* attribute_buffer_copied) { - if (!attribute_buffer_copied) - return E_INVALIDARG; - *attribute_buffer_copied = 0; - if (!attribute_buffer) - return E_INVALIDARG; - if (!input_scope_.get()) - return E_UNEXPECTED; - // We support only input scope attribute. - *attribute_buffer_copied = 0; - if (attribute_buffer_size == 0) - return S_OK; - - attribute_buffer[0].dwOverlapId = 0; - attribute_buffer[0].idAttr = GUID_PROP_INPUTSCOPE; - attribute_buffer[0].varValue.vt = VT_UNKNOWN; - attribute_buffer[0].varValue.punkVal = input_scope_.get(); - attribute_buffer[0].varValue.punkVal->AddRef(); - *attribute_buffer_copied = 1; - return S_OK; -} - -STDMETHODIMP TextStore::SetSelection( - ULONG selection_buffer_size, - const TS_SELECTION_ACP* selection_buffer) { - if (!HasReadWriteLock()) - return TF_E_NOLOCK; - if (selection_buffer_size > 0) { - const LONG start_pos = selection_buffer[0].acpStart; - const LONG end_pos = selection_buffer[0].acpEnd; - if (!((static_cast<LONG>(committed_size_) <= start_pos) && - (start_pos <= end_pos) && - (end_pos <= static_cast<LONG>(string_buffer_.size())))) { - return TF_E_INVALIDPOS; - } - selection_start_ = start_pos; - selection_end_ = end_pos; - } - return S_OK; -} - -STDMETHODIMP TextStore::SetText(DWORD flags, - LONG acp_start, - LONG acp_end, - const wchar_t* text_buffer, - ULONG text_buffer_size, - TS_TEXTCHANGE* text_change) { - if (!HasReadWriteLock()) - return TS_E_NOLOCK; - if (!((static_cast<LONG>(committed_size_) <= acp_start) && - (acp_start <= acp_end) && - (acp_end <= static_cast<LONG>(string_buffer_.size())))) { - return TS_E_INVALIDPOS; - } - - TS_SELECTION_ACP selection; - selection.acpStart = acp_start; - selection.acpEnd = acp_end; - selection.style.ase = TS_AE_NONE; - selection.style.fInterimChar = 0; - - HRESULT ret; - ret = SetSelection(1, &selection); - if (ret != S_OK) - return ret; - - TS_TEXTCHANGE change; - ret = InsertTextAtSelection(0, text_buffer, text_buffer_size, - &acp_start, &acp_end, &change); - if (ret != S_OK) - return ret; - - if (text_change) - *text_change = change; - - return S_OK; -} - -STDMETHODIMP TextStore::UnadviseSink(IUnknown* unknown) { - if (!text_store_acp_sink_.IsSameObject(unknown)) - return CONNECT_E_NOCONNECTION; - text_store_acp_sink_.Release(); - text_store_acp_sink_mask_ = 0; - return S_OK; -} - -STDMETHODIMP TextStore::OnStartComposition( - ITfCompositionView* composition_view, - BOOL* ok) { - if (ok) - *ok = TRUE; - return S_OK; -} - -STDMETHODIMP TextStore::OnUpdateComposition( - ITfCompositionView* composition_view, - ITfRange* range) { - return S_OK; -} - -STDMETHODIMP TextStore::OnEndComposition( - ITfCompositionView* composition_view) { - return S_OK; -} - -STDMETHODIMP TextStore::OnEndEdit(ITfContext* context, - TfEditCookie read_only_edit_cookie, - ITfEditRecord* edit_record) { - if (!context || !edit_record) - return E_INVALIDARG; - if (!GetCompositionStatus(context, read_only_edit_cookie, &committed_size_, - &underlines_)) { - return S_OK; - } - edit_flag_ = true; - return S_OK; -} - -bool TextStore::GetDisplayAttribute(TfGuidAtom guid_atom, - TF_DISPLAYATTRIBUTE* attribute) { - GUID guid; - if (FAILED(category_manager_->GetGUID(guid_atom, &guid))) - return false; - - base::win::ScopedComPtr<ITfDisplayAttributeInfo> display_attribute_info; - if (FAILED(display_attribute_manager_->GetDisplayAttributeInfo( - guid, display_attribute_info.Receive(), NULL))) { - return false; - } - return SUCCEEDED(display_attribute_info->GetAttributeInfo(attribute)); -} - -bool TextStore::GetCompositionStatus( - ITfContext* context, - const TfEditCookie read_only_edit_cookie, - uint32_t* committed_size, - std::vector<metro_viewer::UnderlineInfo>* undelines) { - DCHECK(context); - DCHECK(committed_size); - DCHECK(undelines); - const GUID* rgGuids[2] = {&GUID_PROP_COMPOSING, &GUID_PROP_ATTRIBUTE}; - base::win::ScopedComPtr<ITfReadOnlyProperty> track_property; - if (FAILED(context->TrackProperties(rgGuids, 2, NULL, 0, - track_property.Receive()))) { - return false; - } - - *committed_size = 0; - undelines->clear(); - base::win::ScopedComPtr<ITfRange> start_to_end_range; - base::win::ScopedComPtr<ITfRange> end_range; - if (FAILED(context->GetStart(read_only_edit_cookie, - start_to_end_range.Receive()))) { - return false; - } - if (FAILED(context->GetEnd(read_only_edit_cookie, end_range.Receive()))) - return false; - if (FAILED(start_to_end_range->ShiftEndToRange( - read_only_edit_cookie, end_range.get(), TF_ANCHOR_END))) { - return false; - } - - base::win::ScopedComPtr<IEnumTfRanges> ranges; - if (FAILED(track_property->EnumRanges(read_only_edit_cookie, ranges.Receive(), - start_to_end_range.get()))) { - return false; - } - - while (true) { - base::win::ScopedComPtr<ITfRange> range; - if (ranges->Next(1, range.Receive(), NULL) != S_OK) - return true; - base::win::ScopedVariant value; - base::win::ScopedComPtr<IEnumTfPropertyValue> enum_prop_value; - if (FAILED(track_property->GetValue(read_only_edit_cookie, range.get(), - value.Receive()))) { - return false; - } - if (FAILED(enum_prop_value.QueryFrom(value.AsInput()->punkVal))) - return false; - - TF_PROPERTYVAL property_value; - bool is_composition = false; - metro_viewer::UnderlineInfo underline; - while (enum_prop_value->Next(1, &property_value, NULL) == S_OK) { - if (IsEqualGUID(property_value.guidId, GUID_PROP_COMPOSING)) { - is_composition = (property_value.varValue.lVal == TRUE); - } else if (IsEqualGUID(property_value.guidId, GUID_PROP_ATTRIBUTE)) { - TfGuidAtom guid_atom = - static_cast<TfGuidAtom>(property_value.varValue.lVal); - TF_DISPLAYATTRIBUTE display_attribute; - if (GetDisplayAttribute(guid_atom, &display_attribute)) - underline.thick = !!display_attribute.fBoldLine; - } - VariantClear(&property_value.varValue); - } - - base::win::ScopedComPtr<ITfRangeACP> range_acp; - range_acp.QueryFrom(range.get()); - LONG start_pos, length; - range_acp->GetExtent(&start_pos, &length); - if (is_composition) { - underline.start_offset = start_pos; - underline.end_offset = start_pos + length; - undelines->push_back(underline); - } else if (*committed_size < static_cast<size_t>(start_pos + length)) { - *committed_size = start_pos + length; - } - } -} - -bool TextStore::CancelComposition() { - // If there is an on-going document lock, we must not edit the text. - if (edit_flag_) - return false; - - if (string_buffer_.empty()) - return true; - - // Unlike ImmNotifyIME(NI_COMPOSITIONSTR, CPS_CANCEL, 0) in IMM32, TSF does - // not have a dedicated method to cancel composition. However, CUAS actually - // has a protocol conversion from CPS_CANCEL into TSF operations. According - // to the observations on Windows 7, TIPs are expected to cancel composition - // when an on-going composition text is replaced with an empty string. So - // we use the same operation to cancel composition here to minimize the risk - // of potential compatibility issues. - - const uint32_t previous_buffer_size = - static_cast<uint32_t>(string_buffer_.size()); - string_buffer_.clear(); - committed_size_ = 0; - selection_start_ = 0; - selection_end_ = 0; - if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE) - text_store_acp_sink_->OnSelectionChange(); - if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE) - text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); - if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { - TS_TEXTCHANGE textChange = {}; - textChange.acpStart = 0; - textChange.acpOldEnd = previous_buffer_size; - textChange.acpNewEnd = 0; - text_store_acp_sink_->OnTextChange(0, &textChange); - } - return true; -} - -bool TextStore::ConfirmComposition() { - // If there is an on-going document lock, we must not edit the text. - if (edit_flag_) - return false; - - if (string_buffer_.empty()) - return true; - - // See the comment in TextStore::CancelComposition. - // This logic is based on the observation about how to emulate - // ImmNotifyIME(NI_COMPOSITIONSTR, CPS_COMPLETE, 0) by CUAS. - - const base::string16& composition_text = - string_buffer_.substr(committed_size_); - if (!composition_text.empty()) - delegate_->OnTextCommitted(composition_text); - - const uint32_t previous_buffer_size = - static_cast<uint32_t>(string_buffer_.size()); - string_buffer_.clear(); - committed_size_ = 0; - selection_start_ = 0; - selection_end_ = 0; - if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE) - text_store_acp_sink_->OnSelectionChange(); - if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE) - text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); - if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) { - TS_TEXTCHANGE textChange = {}; - textChange.acpStart = 0; - textChange.acpOldEnd = previous_buffer_size; - textChange.acpNewEnd = 0; - text_store_acp_sink_->OnTextChange(0, &textChange); - } - return true; -} - -void TextStore::SendOnLayoutChange() { - if (text_store_acp_sink_.get() && - (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)) { - text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0); - } -} - -bool TextStore::HasReadLock() const { - return (current_lock_type_ & TS_LF_READ) == TS_LF_READ; -} - -bool TextStore::HasReadWriteLock() const { - return (current_lock_type_ & TS_LF_READWRITE) == TS_LF_READWRITE; -} - -} // namespace metro_driver diff --git a/win8/metro_driver/ime/text_store.h b/win8/metro_driver/ime/text_store.h deleted file mode 100644 index 123a824..0000000 --- a/win8/metro_driver/ime/text_store.h +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright 2013 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_IME_TEXT_STORE_H_ -#define WIN8_METRO_DRIVER_IME_TEXT_STORE_H_ - -#include <atlbase.h> -#include <atlcom.h> -#include <initguid.h> -#include <inputscope.h> -#include <msctf.h> -#include <stdint.h> - -#include <deque> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/strings/string16.h" -#include "base/win/scoped_comptr.h" -#include "ui/metro_viewer/ime_types.h" - -namespace metro_driver { - -class TextStoreDelegate; - -// TextStore is used to interact with the input method via TSF manager. -// TextStore have a string buffer which is manipulated by TSF manager through -// ITextStoreACP interface methods such as SetText(). -// When the input method updates the composition, TextStore calls -// TextInputClient::SetCompositionText(). And when the input method finishes the -// composition, TextStore calls TextInputClient::InsertText() and clears the -// buffer. -// -// How TextStore works: -// - The user enters "a". -// - The input method set composition as "a". -// - TSF manager calls TextStore::RequestLock(). -// - TextStore callbacks ITextStoreACPSink::OnLockGranted(). -// - In OnLockGranted(), TSF manager calls -// - TextStore::OnStartComposition() -// - TextStore::SetText() -// The string buffer is set as "a". -// - TextStore::OnUpdateComposition() -// - TextStore::OnEndEdit() -// TextStore can get the composition information such as underlines. -// - TextStore calls TextInputClient::SetCompositionText(). -// "a" is shown with an underline as composition string. -// - The user enters <space>. -// - The input method set composition as "A". -// - TSF manager calls TextStore::RequestLock(). -// - TextStore callbacks ITextStoreACPSink::OnLockGranted(). -// - In OnLockGranted(), TSF manager calls -// - TextStore::SetText() -// The string buffer is set as "A". -// - TextStore::OnUpdateComposition() -// - TextStore::OnEndEdit() -// - TextStore calls TextInputClient::SetCompositionText(). -// "A" is shown with an underline as composition string. -// - The user enters <enter>. -// - The input method commits "A". -// - TSF manager calls TextStore::RequestLock(). -// - TextStore callbacks ITextStoreACPSink::OnLockGranted(). -// - In OnLockGranted(), TSF manager calls -// - TextStore::OnEndComposition() -// - TextStore::OnEndEdit() -// TextStore knows "A" is committed. -// - TextStore calls TextInputClient::InsertText(). -// "A" is shown as committed string. -// - TextStore clears the string buffer. -// - TextStore calls OnSelectionChange(), OnLayoutChange() and -// OnTextChange() of ITextStoreACPSink to let TSF manager know that the -// string buffer has been changed. -// -// About the locking scheme: -// When TSF manager manipulates the string buffer it calls RequestLock() to get -// the lock of the document. If TextStore can grant the lock request, it -// callbacks ITextStoreACPSink::OnLockGranted(). -// RequestLock() is called from only one thread, but called recursively in -// OnLockGranted() or OnSelectionChange() or OnLayoutChange() or OnTextChange(). -// If the document is locked and the lock request is asynchronous, TextStore -// queues the request. The queued requests will be handled after the current -// lock is removed. -// More information about document locks can be found here: -// http://msdn.microsoft.com/en-us/library/ms538064 -// -// More information about TSF can be found here: -// http://msdn.microsoft.com/en-us/library/ms629032 -class ATL_NO_VTABLE TextStore - : public CComObjectRootEx<CComMultiThreadModel>, - public ITextStoreACP, - public ITfContextOwnerCompositionSink, - public ITfTextEditSink { - public: - virtual ~TextStore(); - - BEGIN_COM_MAP(TextStore) - COM_INTERFACE_ENTRY(ITextStoreACP) - COM_INTERFACE_ENTRY(ITfContextOwnerCompositionSink) - COM_INTERFACE_ENTRY(ITfTextEditSink) - END_COM_MAP() - - // ITextStoreACP: - STDMETHOD(AdviseSink)(REFIID iid, IUnknown* unknown, DWORD mask) override; - STDMETHOD(FindNextAttrTransition)(LONG acp_start, - LONG acp_halt, - ULONG num_filter_attributes, - const TS_ATTRID* filter_attributes, - DWORD flags, - LONG* acp_next, - BOOL* found, - LONG* found_offset) override; - STDMETHOD(GetACPFromPoint)(TsViewCookie view_cookie, - const POINT* point, - DWORD flags, - LONG* acp) override; - STDMETHOD(GetActiveView)(TsViewCookie* view_cookie) override; - STDMETHOD(GetEmbedded)(LONG acp_pos, - REFGUID service, - REFIID iid, - IUnknown** unknown) override; - STDMETHOD(GetEndACP)(LONG* acp) override; - STDMETHOD(GetFormattedText)(LONG acp_start, - LONG acp_end, - IDataObject** data_object) override; - STDMETHOD(GetScreenExt)(TsViewCookie view_cookie, RECT* rect) override; - STDMETHOD(GetSelection)(ULONG selection_index, - ULONG selection_buffer_size, - TS_SELECTION_ACP* selection_buffer, - ULONG* fetched_count) override; - STDMETHOD(GetStatus)(TS_STATUS* pdcs) override; - STDMETHOD(GetText)(LONG acp_start, - LONG acp_end, - wchar_t* text_buffer, - ULONG text_buffer_size, - ULONG* text_buffer_copied, - TS_RUNINFO* run_info_buffer, - ULONG run_info_buffer_size, - ULONG* run_info_buffer_copied, - LONG* next_acp) override; - STDMETHOD(GetTextExt)(TsViewCookie view_cookie, - LONG acp_start, - LONG acp_end, - RECT* rect, - BOOL* clipped) override; - STDMETHOD(GetWnd)(TsViewCookie view_cookie, HWND* window_handle) override; - STDMETHOD(InsertEmbedded)(DWORD flags, - LONG acp_start, - LONG acp_end, - IDataObject* data_object, - TS_TEXTCHANGE* change) override; - STDMETHOD(InsertEmbeddedAtSelection)(DWORD flags, - IDataObject* data_object, - LONG* acp_start, - LONG* acp_end, - TS_TEXTCHANGE* change) override; - STDMETHOD(InsertTextAtSelection)(DWORD flags, - const wchar_t* text_buffer, - ULONG text_buffer_size, - LONG* acp_start, - LONG* acp_end, - TS_TEXTCHANGE* text_change) override; - STDMETHOD(QueryInsert)(LONG acp_test_start, - LONG acp_test_end, - ULONG text_size, - LONG* acp_result_start, - LONG* acp_result_end) override; - STDMETHOD(QueryInsertEmbedded)(const GUID* service, - const FORMATETC* format, - BOOL* insertable) override; - STDMETHOD(RequestAttrsAtPosition)(LONG acp_pos, - ULONG attribute_buffer_size, - const TS_ATTRID* attribute_buffer, - DWORD flags) override; - STDMETHOD(RequestAttrsTransitioningAtPosition)( - LONG acp_pos, - ULONG attribute_buffer_size, - const TS_ATTRID* attribute_buffer, - DWORD flags) override; - STDMETHOD(RequestLock)(DWORD lock_flags, HRESULT* result) override; - STDMETHOD(RequestSupportedAttrs)(DWORD flags, - ULONG attribute_buffer_size, - const TS_ATTRID* attribute_buffer) override; - STDMETHOD(RetrieveRequestedAttrs)(ULONG attribute_buffer_size, - TS_ATTRVAL* attribute_buffer, - ULONG* attribute_buffer_copied) override; - STDMETHOD(SetSelection)(ULONG selection_buffer_size, - const TS_SELECTION_ACP* selection_buffer) override; - STDMETHOD(SetText)(DWORD flags, - LONG acp_start, - LONG acp_end, - const wchar_t* text_buffer, - ULONG text_buffer_size, - TS_TEXTCHANGE* text_change) override; - STDMETHOD(UnadviseSink)(IUnknown* unknown) override; - - // ITfContextOwnerCompositionSink: - STDMETHOD(OnStartComposition)(ITfCompositionView* composition_view, - BOOL* ok) override; - STDMETHOD(OnUpdateComposition)(ITfCompositionView* composition_view, - ITfRange* range) override; - STDMETHOD(OnEndComposition)(ITfCompositionView* composition_view) override; - - // ITfTextEditSink: - STDMETHOD(OnEndEdit)(ITfContext* context, TfEditCookie read_only_edit_cookie, - ITfEditRecord* edit_record) override; - - // Cancels the ongoing composition if exists. - bool CancelComposition(); - - // Confirms the ongoing composition if exists. - bool ConfirmComposition(); - - // Sends OnLayoutChange() via |text_store_acp_sink_|. - void SendOnLayoutChange(); - - // Creates an instance of TextStore. Returns NULL if fails. - static scoped_refptr<TextStore> Create( - HWND window_handle, - const std::vector<InputScope>& input_scopes, - TextStoreDelegate* delegate); - - private: - friend CComObject<TextStore>; - TextStore(); - - void Initialize(HWND window_handle, - ITfCategoryMgr* category_manager, - ITfDisplayAttributeMgr* display_attribute_manager, - ITfInputScope* input_scope, - TextStoreDelegate* delegate); - - // Checks if the document has a read-only lock. - bool HasReadLock() const; - - // Checks if the document has a read and write lock. - bool HasReadWriteLock() const; - - // Gets the display attribute structure. - bool GetDisplayAttribute(TfGuidAtom guid_atom, - TF_DISPLAYATTRIBUTE* attribute); - - // Gets the committed string size and underline information of the context. - bool GetCompositionStatus( - ITfContext* context, - const TfEditCookie read_only_edit_cookie, - uint32_t* committed_size, - std::vector<metro_viewer::UnderlineInfo>* undelines); - - // A pointer of ITextStoreACPSink, this instance is given in AdviseSink. - base::win::ScopedComPtr<ITextStoreACPSink> text_store_acp_sink_; - - // The current mask of |text_store_acp_sink_|. - DWORD text_store_acp_sink_mask_; - - // HWND of the attached window. - HWND window_handle_; - - // |string_buffer_| contains committed string and composition string. - // Example: "aoi" is committed, and "umi" is under composition. - // |string_buffer_|: "aoiumi" - // |committed_size_|: 3 - base::string16 string_buffer_; - uint32_t committed_size_; - - // |selection_start_| and |selection_end_| indicates the selection range. - // Example: "iue" is selected - // |string_buffer_|: "aiueo" - // |selection_start_|: 1 - // |selection_end_|: 4 - uint32_t selection_start_; - uint32_t selection_end_; - - // |start_offset| and |end_offset| of |composition_undelines_| indicates - // the offsets in |string_buffer_|. - // Example: "aoi" is committed. There are two underlines in "umi" and "no". - // |string_buffer_|: "aoiumino" - // |committed_size_|: 3 - // underlines_[0].start_offset: 3 - // underlines_[0].end_offset: 6 - // underlines_[1].start_offset: 6 - // underlines_[1].end_offset: 8 - std::vector<metro_viewer::UnderlineInfo> underlines_; - - // |edit_flag_| indicates that the status is edited during - // ITextStoreACPSink::OnLockGranted(). - bool edit_flag_; - - // The type of current lock. - // 0: No lock. - // TS_LF_READ: read-only lock. - // TS_LF_READWRITE: read/write lock. - DWORD current_lock_type_; - - // Queue of the lock request used in RequestLock(). - std::deque<DWORD> lock_queue_; - - // Category manager and Display attribute manager are used to obtain the - // attributes of the composition string. - base::win::ScopedComPtr<ITfCategoryMgr> category_manager_; - base::win::ScopedComPtr<ITfDisplayAttributeMgr> display_attribute_manager_; - - // Represents the context information of this text. - base::win::ScopedComPtr<ITfInputScope> input_scope_; - - // The delegate attached to this text store. - TextStoreDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(TextStore); -}; - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_TEXT_STORE_H_ diff --git a/win8/metro_driver/ime/text_store_delegate.h b/win8/metro_driver/ime/text_store_delegate.h deleted file mode 100644 index 4a3f03f..0000000 --- a/win8/metro_driver/ime/text_store_delegate.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2013 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_IME_TEXT_STORE_DELEGATE_H_ -#define WIN8_METRO_DRIVER_IME_TEXT_STORE_DELEGATE_H_ - -#include <vector> - -#include <windows.h> -#include <stdint.h> - -#include "base/strings/string16.h" - -namespace metro_viewer { -struct UnderlineInfo; -} - -namespace metro_driver { - -// A delegate which works together with virtual text stores. -// Objects that implement this delegate will receive notifications from a -// virtual text store whenever an IME updates the composition or commits text. -// Objects that implement this delegate are also responsible for calculating -// the character position of composition and caret position upon request. -class TextStoreDelegate { - public: - virtual ~TextStoreDelegate() {} - - // Called when on-going composition is updated. An empty |text| represents - // that the composition is canceled. - virtual void OnCompositionChanged( - const base::string16& text, - int32_t selection_start, - int32_t selection_end, - const std::vector<metro_viewer::UnderlineInfo>& underlines) = 0; - - // Called when |text| is committed. - virtual void OnTextCommitted(const base::string16& text) = 0; - - // Called when an IME requests the caret position. Objects that implement - // this method must return the caret position in screen coordinates. - virtual RECT GetCaretBounds() = 0; - - // Called when an IME requests the bounding box of an character whose - // index is |index| in the on-going composition. position. Objects that - // implement this method must return true and fill the character bounds into - // |rect| in screen coordinates. - // Should return false if |index| is invalid. - virtual bool GetCompositionCharacterBounds(uint32_t index, RECT* rect) = 0; -}; - -} // namespace metro_driver - -#endif // WIN8_METRO_DRIVER_IME_TEXT_STORE_DELEGATE_H_ diff --git a/win8/metro_driver/metro_dialog_box.cc b/win8/metro_driver/metro_dialog_box.cc deleted file mode 100644 index 1217fed..0000000 --- a/win8/metro_driver/metro_dialog_box.cc +++ /dev/null @@ -1,160 +0,0 @@ -// 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.h" -#include "win8/metro_driver/metro_dialog_box.h" -#include "win8/metro_driver/winrt_utils.h" - -typedef winfoundtn::Collections:: - IVector<ABI::Windows::UI::Popups::IUICommand*> WindowsUICommands; - -typedef winfoundtn::IAsyncOperation<ABI::Windows::UI::Popups::IUICommand*> - AsyncCommandStatus; - -MetroDialogBox::MetroDialogBox() { - DVLOG(1) << __FUNCTION__; - dialog_box_info_.button1_handler = NULL; - dialog_box_info_.button2_handler = NULL; -} - -MetroDialogBox::~MetroDialogBox() { - DVLOG(1) << __FUNCTION__; -} - -void MetroDialogBox::Show( - const DialogBoxInfo& dialog_box_info) { - DVLOG(1) << __FUNCTION__; - - // Only one dialog can be displayed at a given time. - DCHECK(dialog_box_.Get() == NULL); - - // The message dialog display does not work correctly in snapped mode. - mswr::ComPtr<winui::Popups::IMessageDialogFactory> message_dialog_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Popups_MessageDialog, - message_dialog_factory.GetAddressOf()); - CheckHR(hr, "Failed to activate IMessageDialogFactory"); - - mswrw::HString message_title; - message_title.Attach(MakeHString(dialog_box_info.title)); - - mswrw::HString message_content; - message_content.Attach(MakeHString(dialog_box_info.content)); - - hr = message_dialog_factory->CreateWithTitle( - message_content.Get(), - message_title.Get(), - dialog_box_.GetAddressOf()); - CheckHR(hr, "Failed to create message dialog"); - - mswr::ComPtr<WindowsUICommands> commands; - hr = dialog_box_->get_Commands(commands.GetAddressOf()); - CheckHR(hr, "Failed to create ui command collection"); - - mswr::ComPtr<winui::Popups::IUICommandFactory> ui_command_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Popups_UICommand, - ui_command_factory.GetAddressOf()); - CheckHR(hr, "Failed to activate IUICommandFactory"); - - mswrw::HString label1; - label1.Attach(MakeHString(dialog_box_info.button1_label)); - - mswr::ComPtr<winui::Popups::IUICommand> label1_command; - hr = ui_command_factory->CreateWithHandler( - label1.Get(), this, label1_command.GetAddressOf()); - CheckHR(hr, "Failed to add button1"); - - mswrw::HString label2; - label2.Attach(MakeHString(dialog_box_info.button2_label)); - - mswr::ComPtr<winui::Popups::IUICommand> label2_command; - hr = ui_command_factory->CreateWithHandler(label2.Get(), this, - label2_command.GetAddressOf()); - CheckHR(hr, "Failed to add button2"); - - commands->Append(label1_command.Get()); - commands->Append(label2_command.Get()); - - mswr::ComPtr<AsyncCommandStatus> ret; - hr = dialog_box_->ShowAsync(ret.GetAddressOf()); - CheckHR(hr, "Failed to show dialog"); - - dialog_box_info_ = dialog_box_info; -} - -// The dialog box displayed via the MessageDialog interface has the class name -// 'Shell_Dialog'. The dialog box is top level window. To find it we enumerate -// all top level windows and compare the class names. If we find a matching -// window class we compare its process id with ours and return the same. -BOOL CALLBACK DialogBoxFinder(HWND hwnd, LPARAM lparam) { - char classname[MAX_PATH] = {0}; - - if (::GetClassNameA(hwnd, classname, ARRAYSIZE(classname))) { - if (lstrcmpiA("Shell_Dialog", classname) == 0) { - if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) { - DVLOG(1) << "Found top most dialog box: " << classname; - DVLOG(1) << "HWND: " << hwnd; - DWORD window_pid = 0; - DWORD window_tid = GetWindowThreadProcessId(hwnd, &window_pid); - DVLOG(1) << "Window tid: " << window_tid; - DVLOG(1) << "Window pid: " << window_pid; - - if (window_pid == ::GetCurrentProcessId()) { - HWND* dialog_window = reinterpret_cast<HWND*>(lparam); - *dialog_window = hwnd; - return FALSE; - } - } - } - } - return TRUE; -} - -void MetroDialogBox::Dismiss() { - DVLOG(1) << __FUNCTION__; - if (!dialog_box_) - return; - - dialog_box_info_.button1_handler = NULL; - dialog_box_info_.button2_handler = NULL; - dialog_box_info_.button1_label.clear(); - dialog_box_info_.button2_label.clear(); - dialog_box_.Reset(); - - // We don't have a good way to dismiss the dialog box. Hack for now is to - // find the dialog box class in our process and close it via the WM_CLOSE - // message. - HWND dialog_box = NULL; - ::EnumWindows(&DialogBoxFinder, reinterpret_cast<LPARAM>(&dialog_box)); - if (::IsWindow(dialog_box)) - PostMessage(dialog_box, WM_CLOSE, 0, 0); -} - -HRESULT STDMETHODCALLTYPE MetroDialogBox::Invoke( - winui::Popups::IUICommand* command) { - DVLOG(1) << __FUNCTION__; - - mswrw::HString label; - command->get_Label(label.GetAddressOf()); - - base::string16 button_label = MakeStdWString(label.Get()); - DVLOG(1) << "Clicked button label is : " << button_label; - if (button_label == dialog_box_info_.button1_label) { - DVLOG(1) << "Button1 clicked"; - DCHECK(dialog_box_info_.button1_handler); - dialog_box_info_.button1_handler(); - } else if (button_label == dialog_box_info_.button2_label) { - DVLOG(1) << "Button2 clicked"; - DCHECK(dialog_box_info_.button2_handler); - dialog_box_info_.button2_handler(); - } - // The dialog box is destroyed once we return from invoke. Go ahead and - // dismiss it. - Dismiss(); - return S_OK; -} - diff --git a/win8/metro_driver/metro_dialog_box.h b/win8/metro_driver/metro_dialog_box.h deleted file mode 100644 index a8ee5b6..0000000 --- a/win8/metro_driver/metro_dialog_box.h +++ /dev/null @@ -1,64 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_METRO_DIALOG_BOX_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_METRO_DIALOG_BOX_H_ - -#include <windows.ui.popups.h> -#include <string> - -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/win/metro.h" - -// Provides functionality to display a dialog box -class MetroDialogBox : public winui::Popups::IUICommandInvokedHandler { - public: - struct DialogBoxInfo { - base::string16 title; - base::string16 content; - base::string16 button1_label; - base::string16 button2_label; - base::win::MetroDialogButtonPressedHandler button1_handler; - base::win::MetroDialogButtonPressedHandler button2_handler; - }; - - MetroDialogBox(); - ~MetroDialogBox(); - - // Displays the dialog box. - void Show(const DialogBoxInfo& dialog_box_info); - - // Dismisses the dialog box. - void Dismiss(); - - // IUICommandInvokedHandler implementation. - // Dummy implementation of IUnknown. This is fine as the lifetime of this - // class is tied to the lifetime of the ChromeAppView instance. - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** object) { - DVLOG(1) << __FUNCTION__; - CHECK(false); - return E_NOINTERFACE; - } - - virtual ULONG STDMETHODCALLTYPE AddRef(void) { - DVLOG(1) << __FUNCTION__; - return 1; - } - - virtual ULONG STDMETHODCALLTYPE Release(void) { - DVLOG(1) << __FUNCTION__; - return 1; - } - - virtual HRESULT STDMETHODCALLTYPE Invoke(winui::Popups::IUICommand* command); - - private: - // The actual dialog box. - mswr::ComPtr<winui::Popups::IMessageDialog> dialog_box_; - DialogBoxInfo dialog_box_info_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_METRO_DIALOG_BOX_H_ - diff --git a/win8/metro_driver/metro_driver.gyp b/win8/metro_driver/metro_driver.gyp deleted file mode 100644 index 663990a..0000000 --- a/win8/metro_driver/metro_driver.gyp +++ /dev/null @@ -1,126 +0,0 @@ -# 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. -{ - 'conditions': [ - ['OS=="win"', { - 'variables': { - 'chromium_code': 1, - }, - 'includes': [ - '../../build/util/version.gypi', - '../../build/win_precompile.gypi', - ], - 'target_defaults': { - 'msvs_settings': { - 'VCLinkerTool': { - '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', - ], - }, - }, - }, - 'targets': [ - { - # GN version: //win8/metro_driver:version_resources - 'target_name': 'metro_driver_version_resources', - 'type': 'none', - 'variables': { - 'output_dir': 'metro_driver', - 'branding_path': '../../chrome/app/theme/<(branding_path_component)/BRANDING', - 'template_input_path': '../../chrome/app/chrome_version.rc.version', - }, - 'sources': [ - 'metro_driver_dll.ver', - ], - 'includes': [ - '../../chrome/version_resource_rules.gypi', - ], - }, - { - # GN version: //win8/metro_driver - 'target_name': 'metro_driver', - 'type': 'shared_library', - 'dependencies': [ - '../../base/base.gyp:base', - '../../chrome/common_constants.gyp:common_constants', - '../../chrome/chrome.gyp:installer_util', - '../../crypto/crypto.gyp:crypto', - '../../ipc/ipc.gyp:ipc', - '../../sandbox/sandbox.gyp:sandbox', - '../../ui/events/events.gyp:events', - '../../ui/metro_viewer/metro_viewer.gyp:metro_viewer_messages', - '../../ui/gfx/gfx.gyp:gfx', - '../../ui/gfx/gfx.gyp:gfx_geometry', - '../../url/url.gyp:url_lib', - 'metro_driver_version_resources', - ], - 'sources': [ - 'display_properties.cc', - 'display_properties.h', - 'stdafx.h', - 'winrt_utils.cc', - 'winrt_utils.h', - '<(SHARED_INTERMEDIATE_DIR)/metro_driver/metro_driver_dll_version.rc', - ], - 'conditions': [ - ['use_aura==1', { - 'sources': [ - 'direct3d_helper.cc', - 'direct3d_helper.h', - ], - 'includes': [ - 'ime/ime.gypi', - ], - }, { # use_aura!=1 - 'sources': [ - 'chrome_app_view.cc', - 'chrome_app_view.h', - 'chrome_url_launch_handler.cc', - 'chrome_url_launch_handler.h', - 'devices_handler.cc', - 'devices_handler.h', - 'metro_dialog_box.cc', - 'metro_dialog_box.h', - 'print_document_source.cc', - 'print_document_source.h', - 'print_handler.cc', - 'print_handler.h', - 'secondary_tile.cc', - 'secondary_tile.h', - 'settings_handler.cc', - 'settings_handler.h', - 'toast_notification_handler.cc', - 'toast_notification_handler.h', - ], - }], - ], - }, - { - # GN version: //win8/metro_driver:metro_driver_unittests - 'target_name': 'metro_driver_unittests', - 'type': 'executable', - 'dependencies': [ - '../../base/base.gyp:base', - '../../chrome/chrome.gyp:installer_util', - '../../testing/gtest.gyp:gtest', - 'metro_driver', - ], - 'sources': [ - 'run_all_unittests.cc', - 'winrt_utils.cc', - 'winrt_utils.h', - 'winrt_utils_unittest.cc', - ], - }, - ], - },], - ], -} diff --git a/win8/metro_driver/metro_driver_dll.ver b/win8/metro_driver/metro_driver_dll.ver deleted file mode 100644 index 72d1cc8..0000000 --- a/win8/metro_driver/metro_driver_dll.ver +++ /dev/null @@ -1,2 +0,0 @@ -INTERNAL_NAME=metro_driver_dll -ORIGINAL_FILENAME=metro_driver.dll diff --git a/win8/metro_driver/print_document_source.cc b/win8/metro_driver/print_document_source.cc deleted file mode 100644 index 3d371da..0000000 --- a/win8/metro_driver/print_document_source.cc +++ /dev/null @@ -1,529 +0,0 @@ -// 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 "stdafx.h" -#include "win8/metro_driver/print_document_source.h" - -#include <stddef.h> -#include <stdint.h> -#include <windows.graphics.display.h> - -#include "base/logging.h" -#include "base/numerics/safe_conversions.h" - - -namespace { - -class D2DFactoryAutoLock { - public: - explicit D2DFactoryAutoLock(ID2D1Factory* d2d_factory) { - HRESULT hr = d2d_factory->QueryInterface(IID_PPV_ARGS(&d2d_multithread_)); - if (d2d_multithread_.Get()) - d2d_multithread_->Enter(); - else - NOTREACHED() << "Failed to QI for ID2D1Multithread " << std::hex << hr; - } - - ~D2DFactoryAutoLock() { - if (d2d_multithread_.Get()) - d2d_multithread_->Leave(); - } - - private: - mswr::ComPtr<ID2D1Multithread> d2d_multithread_; -}; - -// TODO(mad): remove once we don't run mixed SDK/OS anymore. -const GUID kOldPackageTargetGuid = - {0xfb2a33c0, 0x8c35, 0x465f, - {0xbe, 0xd5, 0x9f, 0x36, 0x89, 0x51, 0x77, 0x52}}; -const GUID kNewPackageTargetGuid = - {0x1a6dd0ad, 0x1e2a, 0x4e99, - {0xa5, 0xba, 0x91, 0xf1, 0x78, 0x18, 0x29, 0x0e}}; - - -} // namespace - -namespace metro_driver { - -PrintDocumentSource::PrintDocumentSource() - : page_count_ready_(true, false), - parent_lock_(NULL), - height_(0), - width_(0), - dpi_(96), - aborted_(false), - using_old_preview_interface_(false) { -} - -HRESULT PrintDocumentSource::RuntimeClassInitialize( - const DirectXContext& directx_context, - base::Lock* parent_lock) { - DCHECK(parent_lock != NULL); - DCHECK(directx_context.d2d_context.Get() != NULL); - DCHECK(directx_context.d2d_device.Get() != NULL); - DCHECK(directx_context.d2d_factory.Get() != NULL); - DCHECK(directx_context.d3d_device.Get() != NULL); - DCHECK(directx_context.wic_factory.Get() != NULL); - directx_context_ = directx_context; - - // No other method can be called before RuntimeClassInitialize which is called - // during the construction via mswr::MakeAndInitialize(), so it's safe for all - // other methods to use the parent_lock_ without checking if it's NULL. - DCHECK(parent_lock_ == NULL); - parent_lock_ = parent_lock; - - return S_OK; -} - -void PrintDocumentSource::Abort() { - base::AutoLock lock(*parent_lock_); - aborted_ = true; - if (page_count_ready_.IsSignaled()) { - pages_.clear(); - for (size_t i = 0; i < pages_ready_state_.size(); ++i) - pages_ready_state_[i]->Broadcast(); - } else { - DCHECK(pages_.empty() && pages_ready_state_.empty()); - } -} - -STDMETHODIMP PrintDocumentSource::GetPreviewPageCollection( - IPrintDocumentPackageTarget* package_target, - IPrintPreviewPageCollection** page_collection) { - DVLOG(1) << __FUNCTION__; - DCHECK(package_target != NULL); - DCHECK(page_collection != NULL); - - HRESULT hr = package_target->GetPackageTarget( - __uuidof(IPrintPreviewDxgiPackageTarget), - IID_PPV_ARGS(&dxgi_preview_target_)); - if (FAILED(hr)) { - // TODO(mad): remove once we don't run mixed SDK/OS anymore. - // The IID changed from one version of the SDK to another, so try the other - // one in case we are running a build from a different SDK than the one - // related to the OS version we are running. - GUID package_target_uuid = kNewPackageTargetGuid; - if (package_target_uuid == __uuidof(IPrintPreviewDxgiPackageTarget)) { - package_target_uuid = kOldPackageTargetGuid; - using_old_preview_interface_ = true; - } - hr = package_target->GetPackageTarget(package_target_uuid, - package_target_uuid, - &dxgi_preview_target_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get IPrintPreviewDXGIPackageTarget " << std::hex - << hr; - return hr; - } - } else { - using_old_preview_interface_ = (__uuidof(IPrintPreviewDxgiPackageTarget) == - kOldPackageTargetGuid); - } - - mswr::ComPtr<IPrintPreviewPageCollection> preview_page_collection; - mswr::ComPtr<PrintDocumentSource> print_document_source(this); - hr = print_document_source.As(&preview_page_collection); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get preview_page_collection " << std::hex << hr; - return hr; - } - - hr = preview_page_collection.CopyTo(page_collection); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to copy preview_page_collection " << std::hex << hr; - return hr; - } - return hr; -} - -STDMETHODIMP PrintDocumentSource::MakeDocument( - IInspectable* options, - IPrintDocumentPackageTarget* package_target) { - DVLOG(1) << __FUNCTION__; - DCHECK(options != NULL); - DCHECK(package_target != NULL); - - mswr::ComPtr<wingfx::Printing::IPrintTaskOptionsCore> print_task_options; - HRESULT hr = options->QueryInterface( - wingfx::Printing::IID_IPrintTaskOptionsCore, - reinterpret_cast<void**>(print_task_options.GetAddressOf())); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IPrintTaskOptionsCore " << std::hex << hr; - return hr; - } - - // Use the first page's description for the whole document. Page numbers - // are 1-based in this context. - // TODO(mad): Check if it would be useful to use per page descriptions. - wingfx::Printing::PrintPageDescription page_desc = {}; - hr = print_task_options->GetPageDescription(1 /* page */, &page_desc); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to GetPageDescription " << std::hex << hr; - return hr; - } - - D2D1_PRINT_CONTROL_PROPERTIES print_control_properties; - if (page_desc.DpiX > page_desc.DpiY) - print_control_properties.rasterDPI = static_cast<float>(page_desc.DpiY); - else - print_control_properties.rasterDPI = static_cast<float>(page_desc.DpiX); - - // Color space for vector graphics in D2D print control. - print_control_properties.colorSpace = D2D1_COLOR_SPACE_SRGB; - print_control_properties.fontSubset = D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT; - - mswr::ComPtr<ID2D1PrintControl> print_control; - hr = directx_context_.d2d_device->CreatePrintControl( - directx_context_.wic_factory.Get(), - package_target, - print_control_properties, - print_control.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreatePrintControl " << std::hex << hr; - return hr; - } - - D2D1_SIZE_F page_size = D2D1::SizeF(page_desc.PageSize.Width, - page_desc.PageSize.Height); - - // Wait for the number of pages to be available. - // If an abort occured, we'll get 0 and won't enter the loop below. - size_t page_count = WaitAndGetPageCount(); - - mswr::ComPtr<ID2D1GdiMetafile> gdi_metafile; - for (size_t page = 0; page < page_count; ++page) { - gdi_metafile.Reset(); - hr = WaitAndGetPage(page, gdi_metafile.GetAddressOf()); - LOG_IF(ERROR, FAILED(hr)) << "Failed to get page's metafile " << std::hex - << hr; - // S_FALSE means we got aborted. - if (hr == S_FALSE || FAILED(hr)) - break; - hr = PrintPage(print_control.Get(), gdi_metafile.Get(), page_size); - if (FAILED(hr)) - break; - } - - HRESULT close_hr = print_control->Close(); - if (FAILED(close_hr) && SUCCEEDED(hr)) - return close_hr; - else - return hr; -} - -STDMETHODIMP PrintDocumentSource::Paginate(uint32_t page, - IInspectable* options) { - DVLOG(1) << __FUNCTION__ << ", page = " << page; - DCHECK(options != NULL); - // GetPreviewPageCollection must have been successfuly called. - DCHECK(dxgi_preview_target_.Get() != NULL); - - // Get print settings from PrintTaskOptions for preview, such as page - // description, which contains page size, imageable area, DPI. - // TODO(mad): obtain other print settings in the same way, such as ColorMode, - // NumberOfCopies, etc... - mswr::ComPtr<wingfx::Printing::IPrintTaskOptionsCore> print_options; - HRESULT hr = options->QueryInterface( - wingfx::Printing::IID_IPrintTaskOptionsCore, - reinterpret_cast<void**>(print_options.GetAddressOf())); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IPrintTaskOptionsCore " << std::hex << hr; - return hr; - } - - wingfx::Printing::PrintPageDescription page_desc = {}; - hr = print_options->GetPageDescription(1 /* page */, &page_desc); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to GetPageDescription " << std::hex << hr; - return hr; - } - - width_ = page_desc.PageSize.Width; - height_ = page_desc.PageSize.Height; - - hr = dxgi_preview_target_->InvalidatePreview(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to InvalidatePreview " << std::hex << hr; - return hr; - } - - size_t page_count = WaitAndGetPageCount(); - // A page_count of 0 means abort... - if (page_count == 0) - return S_FALSE; - hr = dxgi_preview_target_->SetJobPageCount( - PageCountType::FinalPageCount, - base::checked_cast<UINT32>(page_count)); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to SetJobPageCount " << std::hex << hr; - return hr; - } - return hr; -} - -STDMETHODIMP PrintDocumentSource::MakePage(uint32_t job_page, - float width, - float height) { - DVLOG(1) << __FUNCTION__ << ", width: " << width << ", height: " << height - << ", job_page: " << job_page; - DCHECK(width > 0 && height > 0); - // Paginate must have been called before this. - if (width_ <= 0.0 || height_ <= 0.0) - return S_FALSE; - - // When job_page is JOB_PAGE_APPLICATION_DEFINED, it means a new preview - // begins. TODO(mad): Double check if we need to cancel pending resources. - if (job_page == JOB_PAGE_APPLICATION_DEFINED) - job_page = 1; - - winfoundtn::Size preview_size; - preview_size.Width = width; - preview_size.Height = height; - float scale = width_ / width; - - mswr::ComPtr<ID2D1Factory> factory; - directx_context_.d2d_device->GetFactory(&factory); - - mswr::ComPtr<ID2D1GdiMetafile> gdi_metafile; - HRESULT hr = WaitAndGetPage(job_page - 1, gdi_metafile.GetAddressOf()); - LOG_IF(ERROR, FAILED(hr)) << "Failed to get page's metafile " << std::hex - << hr; - // Again, S_FALSE means we got aborted. - if (hr == S_FALSE || FAILED(hr)) - return hr; - - // We are accessing D3D resources directly without D2D's knowledge, so we - // must manually acquire the D2D factory lock. - D2DFactoryAutoLock factory_lock(directx_context_.d2d_factory.Get()); - - CD3D11_TEXTURE2D_DESC texture_desc( - DXGI_FORMAT_B8G8R8A8_UNORM, - static_cast<UINT32>(ceil(width * dpi_ / 96)), - static_cast<UINT32>(ceil(height * dpi_ / 96)), - 1, - 1, - D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE - ); - mswr::ComPtr<ID3D11Texture2D> texture; - hr = directx_context_.d3d_device->CreateTexture2D( - &texture_desc, NULL, &texture); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create a 2D texture " << std::hex << hr; - return hr; - } - - mswr::ComPtr<IDXGISurface> dxgi_surface; - hr = texture.As<IDXGISurface>(&dxgi_surface); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IDXGISurface " << std::hex << hr; - return hr; - } - - // D2D device contexts are stateful, and hence a unique device context must - // be used on each call. - mswr::ComPtr<ID2D1DeviceContext> d2d_context; - hr = directx_context_.d2d_device->CreateDeviceContext( - D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2d_context); - - d2d_context->SetDpi(dpi_, dpi_); - - mswr::ComPtr<ID2D1Bitmap1> d2dSurfaceBitmap; - hr = d2d_context->CreateBitmapFromDxgiSurface(dxgi_surface.Get(), - NULL, // default properties. - &d2dSurfaceBitmap); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateBitmapFromDxgiSurface " << std::hex << hr; - return hr; - } - - d2d_context->SetTarget(d2dSurfaceBitmap.Get()); - d2d_context->BeginDraw(); - d2d_context->Clear(); - d2d_context->SetTransform(D2D1::Matrix3x2F(1/scale, 0, 0, 1/scale, 0, 0)); - d2d_context->DrawGdiMetafile(gdi_metafile.Get()); - - hr = d2d_context->EndDraw(); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to EndDraw " << std::hex << hr; - return hr; - } - -// TODO(mad): remove once we don't run mixed SDK/OS anymore. -#ifdef __IPrintPreviewDxgiPackageTarget_FWD_DEFINED__ - FLOAT dpi = dpi_; - if (using_old_preview_interface_) { - // We compiled with the new API but run on the old OS, so we must cheat - // and send something that looks like a float but has a UINT32 value. - *reinterpret_cast<UINT32*>(&dpi) = static_cast<UINT32>(dpi_); - } -#else - UINT32 dpi = static_cast<UINT32>(dpi_); - if (!using_old_preview_interface_) { - // We compiled with the old API but run on the new OS, so we must cheat - // and send something that looks like a UINT32 but has a float value. - *reinterpret_cast<FLOAT*>(&dpi) = dpi_; - } -#endif // __IPrintPreviewDxgiPackageTarget_FWD_DEFINED__ - hr = dxgi_preview_target_->DrawPage(job_page, dxgi_surface.Get(), dpi, dpi); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to DrawPage " << std::hex << hr; - return hr; - } - return hr; -} - -void PrintDocumentSource::ResetDpi(float dpi) { - { - base::AutoLock lock(*parent_lock_); - if (dpi == dpi_) - return; - dpi_ = dpi; - } - directx_context_.d2d_context->SetDpi(dpi, dpi); -} - -void PrintDocumentSource::SetPageCount(size_t page_count) { - DCHECK(page_count > 0); - { - base::AutoLock lock(*parent_lock_); - DCHECK(!page_count_ready_.IsSignaled()); - DCHECK(pages_.empty() && pages_ready_state_.empty()); - - pages_.resize(page_count); - pages_ready_state_.resize(page_count); - - for (size_t i = 0; i < page_count; ++i) - pages_ready_state_[i] = new base::ConditionVariable(parent_lock_); - } - page_count_ready_.Signal(); -} - -void PrintDocumentSource::AddPage(size_t page_number, - IStream* metafile_stream) { - DCHECK(metafile_stream != NULL); - base::AutoLock lock(*parent_lock_); - - DCHECK(page_count_ready_.IsSignaled()); - DCHECK(page_number < pages_.size()); - - pages_[page_number] = metafile_stream; - pages_ready_state_[page_number]->Signal(); -} - -HRESULT PrintDocumentSource::PrintPage(ID2D1PrintControl* print_control, - ID2D1GdiMetafile* gdi_metafile, - D2D1_SIZE_F page_size) { - DVLOG(1) << __FUNCTION__ << ", page_size: (" << page_size.width << ", " - << page_size.height << ")"; - DCHECK(print_control != NULL); - DCHECK(gdi_metafile != NULL); - - // D2D device contexts are stateful, and hence a unique device context must - // be used on each call. - mswr::ComPtr<ID2D1DeviceContext> d2d_context; - HRESULT hr = directx_context_.d2d_device->CreateDeviceContext( - D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2d_context); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateDeviceContext " << std::hex << hr; - return hr; - } - - mswr::ComPtr<ID2D1CommandList> print_command_list; - hr = d2d_context->CreateCommandList(&print_command_list); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateCommandList " << std::hex << hr; - return hr; - } - - d2d_context->SetTarget(print_command_list.Get()); - - d2d_context->BeginDraw(); - d2d_context->DrawGdiMetafile(gdi_metafile); - hr = d2d_context->EndDraw(); - LOG_IF(ERROR, FAILED(hr)) << "Failed to EndDraw " << std::hex << hr; - - // Make sure to always close the command list. - HRESULT close_hr = print_command_list->Close(); - LOG_IF(ERROR, FAILED(close_hr)) << "Failed to close command list " << std::hex - << hr; - if (SUCCEEDED(hr) && SUCCEEDED(close_hr)) - hr = print_control->AddPage(print_command_list.Get(), page_size, NULL); - if (FAILED(hr)) - return hr; - else - return close_hr; -} - -size_t PrintDocumentSource::WaitAndGetPageCount() { - // Properly protect the wait/access to the page count. - { - base::AutoLock lock(*parent_lock_); - if (aborted_) - return 0; - DCHECK(pages_.size() == pages_ready_state_.size()); - if (!pages_.empty()) - return pages_.size(); - } - page_count_ready_.Wait(); - { - base::AutoLock lock(*parent_lock_); - if (!aborted_) { - DCHECK(pages_.size() == pages_ready_state_.size()); - return pages_.size(); - } - } - // A page count of 0 means abort. - return 0; -} - -HRESULT PrintDocumentSource::WaitAndGetPage(size_t page_number, - ID2D1GdiMetafile** gdi_metafile) { - // Properly protect the wait/access to the page data. - base::AutoLock lock(*parent_lock_); - // Make sure we weren't canceled before getting here. - // And the page count should have been received before we get here too. - if (aborted_) - return S_FALSE; - - // We shouldn't be asked for a page until we got the page count. - DCHECK(page_count_ready_.IsSignaled()); - DCHECK(page_number <= pages_ready_state_.size()); - DCHECK(pages_.size() == pages_ready_state_.size()); - while (!aborted_ && pages_[page_number].Get() == NULL) - pages_ready_state_[page_number]->Wait(); - - // Make sure we weren't aborted while we waited unlocked. - if (aborted_) - return S_FALSE; - DCHECK(page_number < pages_.size()); - - mswr::ComPtr<ID2D1Factory> factory; - directx_context_.d2d_device->GetFactory(&factory); - - mswr::ComPtr<ID2D1Factory1> factory1; - HRESULT hr = factory.As(&factory1); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for ID2D1Factory1 " << std::hex << hr; - return hr; - } - - ULARGE_INTEGER result; - LARGE_INTEGER seek_pos; - seek_pos.QuadPart = 0; - hr = pages_[page_number]->Seek(seek_pos, STREAM_SEEK_SET, &result); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to Seek page stream " << std::hex << hr; - return hr; - } - - hr = factory1->CreateGdiMetafile(pages_[page_number].Get(), gdi_metafile); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CreateGdiMetafile " << std::hex << hr; - return hr; - } - return hr; -} - -} // namespace metro_driver diff --git a/win8/metro_driver/print_document_source.h b/win8/metro_driver/print_document_source.h deleted file mode 100644 index 8f3d53b..0000000 --- a/win8/metro_driver/print_document_source.h +++ /dev/null @@ -1,165 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_ - -#include <documentsource.h> -#include <printpreview.h> -#include <stddef.h> -#include <stdint.h> -#include <windows.graphics.printing.h> - -#include <vector> - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_vector.h" -#include "base/synchronization/condition_variable.h" -#include "base/synchronization/waitable_event.h" -#include "win8/metro_driver/winrt_utils.h" - -// Hack to be removed once we don't need to build with an SDK earlier than -// 8441 where the name of the interface has been changed. -// TODO(mad): remove once we don't run mixed SDK/OS anymore. -#ifndef __IPrintPreviewDxgiPackageTarget_FWD_DEFINED__ -typedef IPrintPreviewDXGIPackageTarget IPrintPreviewDxgiPackageTarget; -#endif - - -namespace base { -class Lock; -}; // namespace base - -namespace metro_driver { - -// This class is given to Metro as a source for print documents. -// The methodless IPrintDocumentSource interface is used to identify it as such. -// Then, the other interfaces are used to generate preview and print documents. -// It also exposes a few methods for the print handler to control the document. -class PrintDocumentSource - : public mswr::RuntimeClass< - mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>, - wingfx::Printing::IPrintDocumentSource, - IPrintDocumentPageSource, - IPrintPreviewPageCollection> { - public: - // A set of interfaces for the DirectX context that our parent owns - // and that don't need to change from document to document. - struct DirectXContext { - DirectXContext() {} - DirectXContext(ID3D11Device1* device_3d, - ID2D1Factory1* factory_2d, - ID2D1Device* device_2d, - ID2D1DeviceContext* context_2d, - IWICImagingFactory2* factory_wic) - : d3d_device(device_3d), - d2d_factory(factory_2d), - d2d_device(device_2d), - d2d_context(context_2d), - wic_factory(factory_wic) { - } - DirectXContext(const DirectXContext& other) - : d3d_device(other.d3d_device), - d2d_factory(other.d2d_factory), - d2d_device(other.d2d_device), - d2d_context(other.d2d_context), - wic_factory(other.wic_factory) { - } - mswr::ComPtr<ID3D11Device1> d3d_device; - mswr::ComPtr<ID2D1Factory1> d2d_factory; - mswr::ComPtr<ID2D1Device> d2d_device; - mswr::ComPtr<ID2D1DeviceContext> d2d_context; - mswr::ComPtr<IWICImagingFactory2> wic_factory; - }; - - // Construction / Initialization. - explicit PrintDocumentSource(); - HRESULT RuntimeClassInitialize(const DirectXContext& directx_context, - base::Lock* parent_lock); - // Aborts any pending asynchronous operation. - void Abort(); - - // classic COM interface IPrintDocumentPageSource methods - STDMETHOD(GetPreviewPageCollection) ( - IPrintDocumentPackageTarget* package_target, - IPrintPreviewPageCollection** page_collection); - STDMETHOD(MakeDocument)(IInspectable* options, - IPrintDocumentPackageTarget* package_target); - - // classic COM interface IPrintPreviewPageCollection methods - STDMETHOD(Paginate)(uint32_t page, IInspectable* options); - STDMETHOD(MakePage)(uint32_t desired_page, float width, float height); - - // If the screen DPI changes, we must be warned here. - void ResetDpi(float dpi); - - // When the page count is known, this is called and we can setup our data. - void SetPageCount(size_t page_count); - - // Every time a page is ready, this is called and we can read the data if - // we were waiting for it, or store it for later use. - void AddPage(size_t page_number, IStream* metafile_stream); - - private: - // Print the page given in the metafile stream to the given print control. - HRESULT PrintPage(ID2D1PrintControl* print_control, - ID2D1GdiMetafile* metafile_stream, - D2D1_SIZE_F pageSize); - - // Helper function to wait for the page count to be ready. - // Returns 0 when aborted. - size_t WaitAndGetPageCount(); - - // Helper function to wait for a given page to be ready. - // Returns S_FALSE when aborted. - HRESULT WaitAndGetPage(size_t page_number, - ID2D1GdiMetafile** metafile_stream); - - DirectXContext directx_context_; - - // Once page data is available, it's added to this vector. - std::vector<mswr::ComPtr<IStream>> pages_; - - // When page count is set, the size of this vector is set to that number. - // Then, every time page data is added to pages_, the associated condition - // variable in this vector is signaled. This is only filled when we receive - // the page count, so we must wait on page_count_ready_ before accessing - // the content of this vector. - ScopedVector<base::ConditionVariable> pages_ready_state_; - - // This event is signaled when we receive a page count from Chrome. We should - // not receive any page data before the count, so we can check this event - // while waiting for pages too, in case we ask for page data before we got - // the count, so before we properly initialized pages_ready_state_. - base::WaitableEvent page_count_ready_; - - // The preview target interface set from within GetPreviewPageCollection - // but used from within MakePage. - mswr::ComPtr<IPrintPreviewDxgiPackageTarget> dxgi_preview_target_; - - // Our parent's lock (to make sure it is initialized and destroyed early - // enough), which we use to protect access to our data members. - base::Lock* parent_lock_; - - // The width/height requested in Paginate and used in MakePage. - // TODO(mad): Height is currently not used, and width is only used for - // scaling. We need to add a way to specify width and height when we request - // pages from Chrome. - float height_; - float width_; - - // The DPI is set by Windows and we need to give it to DirectX. - float dpi_; - - // A flag identiying that we have been aborted. Needed to properly handle - // asynchronous callbacks. - bool aborted_; - - // TODO(mad): remove once we don't run mixed SDK/OS anymore. - bool using_old_preview_interface_; -}; - -} // namespace metro_driver - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_ diff --git a/win8/metro_driver/print_handler.cc b/win8/metro_driver/print_handler.cc deleted file mode 100644 index 3911a8b..0000000 --- a/win8/metro_driver/print_handler.cc +++ /dev/null @@ -1,491 +0,0 @@ -// 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 "stdafx.h" -#include "win8/metro_driver/print_handler.h" - -#include <stddef.h> -#include <windows.graphics.display.h> - -#include "base/bind.h" -#include "base/logging.h" -#include "base/numerics/safe_conversions.h" -#include "chrome/app/chrome_command_ids.h" -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintManager*, - wingfx::Printing::PrintTaskRequestedEventArgs*> PrintRequestedHandler; - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintTask*, - wingfx::Printing::PrintTaskCompletedEventArgs*> PrintTaskCompletedHandler; - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintTask*, IInspectable*> PrintTaskInspectableHandler; - -typedef winfoundtn::ITypedEventHandler< - wingfx::Printing::PrintTask*, - wingfx::Printing::PrintTaskProgressingEventArgs*> - PrintTaskProgressingHandler; - -} // namespace - -namespace metro_driver { - -mswr::ComPtr<PrintDocumentSource> PrintHandler::current_document_source_; -bool PrintHandler::printing_enabled_ = false; -base::Lock* PrintHandler::lock_ = NULL; -base::Thread* PrintHandler::thread_ = NULL; - -PrintHandler::PrintHandler() { - DCHECK(lock_ == NULL); - lock_ = new base::Lock(); - - DCHECK(thread_ == NULL); - thread_ = new base::Thread("Metro Print Handler"); - thread_->Start(); -} - -PrintHandler::~PrintHandler() { - ClearPrintTask(); - DCHECK(current_document_source_.Get() == NULL); - - // Get all pending tasks to complete cleanly by Stopping the thread. - // They should complete quickly since current_document_source_ is NULL. - DCHECK(thread_ != NULL); - DCHECK(thread_->IsRunning()); - thread_->Stop(); - delete thread_; - thread_ = NULL; - - DCHECK(lock_ != NULL); - delete lock_; - lock_ = NULL; -} - -HRESULT PrintHandler::Initialize(winui::Core::ICoreWindow* window) { - // Register for Print notifications. - mswr::ComPtr<wingfx::Printing::IPrintManagerStatic> print_mgr_static; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Printing_PrintManager, - print_mgr_static.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create PrintManagerStatic " << std::hex << hr; - return hr; - } - - mswr::ComPtr<wingfx::Printing::IPrintManager> print_mgr; - hr = print_mgr_static->GetForCurrentView(&print_mgr); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get PrintManager for current view " << std::hex - << hr; - return hr; - } - - hr = print_mgr->add_PrintTaskRequested( - mswr::Callback<PrintRequestedHandler>( - this, &PrintHandler::OnPrintRequested).Get(), - &print_requested_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to register PrintTaskRequested " - << std::hex << hr; - - mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Display_DisplayProperties, - display_properties.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create DisplayPropertiesStatics " << std::hex - << hr; - return hr; - } - - hr = display_properties->add_LogicalDpiChanged( - mswr::Callback< - wingfx::Display::IDisplayPropertiesEventHandler, - PrintHandler>(this, &PrintHandler::LogicalDpiChanged).Get(), - &dpi_change_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to register LogicalDpiChanged " - << std::hex << hr; - - // This flag adds support for surfaces with a different color channel - // ordering than the API default. It is recommended usage, and is required - // for compatibility with Direct2D. - UINT creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; -#if defined(_DEBUG) - creation_flags |= D3D11_CREATE_DEVICE_DEBUG; -#endif - - // This array defines the set of DirectX hardware feature levels we support. - // The ordering MUST be preserved. All applications are assumed to support - // 9.1 unless otherwise stated by the application, which is not our case. - D3D_FEATURE_LEVEL feature_levels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1 }; - - mswr::ComPtr<ID3D11Device> device; - mswr::ComPtr<ID3D11DeviceContext> context; - hr = D3D11CreateDevice( - NULL, // Specify null to use the default adapter. - D3D_DRIVER_TYPE_HARDWARE, - 0, // Leave as 0 unless software device. - creation_flags, - feature_levels, - ARRAYSIZE(feature_levels), - D3D11_SDK_VERSION, // Must always use this value in Metro apps. - &device, - NULL, // Returns feature level of device created. - &context); - if (hr == DXGI_ERROR_UNSUPPORTED) { - // The hardware is not supported, try a reference driver instead. - hr = D3D11CreateDevice( - NULL, // Specify null to use the default adapter. - D3D_DRIVER_TYPE_REFERENCE, - 0, // Leave as 0 unless software device. - creation_flags, - feature_levels, - ARRAYSIZE(feature_levels), - D3D11_SDK_VERSION, // Must always use this value in Metro apps. - &device, - NULL, // Returns feature level of device created. - &context); - } - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create D3D11 device/context " << std::hex << hr; - return hr; - } - - hr = device.As(&directx_context_.d3d_device); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI D3D11 device " << std::hex << hr; - return hr; - } - - D2D1_FACTORY_OPTIONS options; - ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS)); - -#if defined(_DEBUG) - options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; -#endif - - hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, - __uuidof(ID2D1Factory1), - &options, - &directx_context_.d2d_factory); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create D2D1 factory " << std::hex << hr; - return hr; - } - - mswr::ComPtr<IDXGIDevice> dxgi_device; - hr = directx_context_.d3d_device.As(&dxgi_device); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to QI for IDXGIDevice " << std::hex << hr; - return hr; - } - - hr = directx_context_.d2d_factory->CreateDevice( - dxgi_device.Get(), &directx_context_.d2d_device); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to Create D2DDevice " << std::hex << hr; - return hr; - } - - hr = directx_context_.d2d_device->CreateDeviceContext( - D2D1_DEVICE_CONTEXT_OPTIONS_NONE, - &directx_context_.d2d_context); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to Create D2DDeviceContext " << std::hex << hr; - return hr; - } - - hr = CoCreateInstance(CLSID_WICImagingFactory, - NULL, - CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&directx_context_.wic_factory)); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to CoCreate WICImagingFactory " << std::hex << hr; - return hr; - } - return hr; -} - -void PrintHandler::EnablePrinting(bool printing_enabled) { - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnEnablePrinting, printing_enabled)); -} - -void PrintHandler::SetPageCount(size_t page_count) { - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnSetPageCount, page_count)); -} - -void PrintHandler::AddPage(size_t page_number, IStream* metafile_stream) { - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnAddPage, - page_number, - mswr::ComPtr<IStream>(metafile_stream))); -} - -void PrintHandler::ShowPrintUI() { - // Post the print UI request over to the metro thread. - DCHECK(globals.appview_msg_loop != NULL); - bool posted = globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&metro_driver::PrintHandler::OnShowPrintUI)); - DCHECK(posted); -} - -HRESULT PrintHandler::OnPrintRequested( - wingfx::Printing::IPrintManager* print_mgr, - wingfx::Printing::IPrintTaskRequestedEventArgs* event_args) { - DVLOG(1) << __FUNCTION__; - - HRESULT hr = S_OK; - if (printing_enabled_) { - mswr::ComPtr<wingfx::Printing::IPrintTaskRequest> print_request; - hr = event_args->get_Request(print_request.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get the Print Task request " << std::hex << hr; - return hr; - } - - mswrw::HString title; - title.Attach(MakeHString(L"Printing")); - hr = print_request->CreatePrintTask( - title.Get(), - mswr::Callback< - wingfx::Printing::IPrintTaskSourceRequestedHandler, - PrintHandler>(this, &PrintHandler::OnPrintTaskSourceRequest).Get(), - print_task_.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create the Print Task " << std::hex << hr; - return hr; - } - - hr = print_task_->add_Completed( - mswr::Callback<PrintTaskCompletedHandler>( - this, &PrintHandler::OnCompleted).Get(), &print_completed_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to create the Print Task " << std::hex - << hr; - } - return hr; -} - -HRESULT PrintHandler::OnPrintTaskSourceRequest( - wingfx::Printing::IPrintTaskSourceRequestedArgs* args) { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<PrintDocumentSource> print_document_source; - HRESULT hr = mswr::MakeAndInitialize<PrintDocumentSource>( - &print_document_source, directx_context_, lock_); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to create document source " << std::hex << hr; - return hr; - } - - print_document_source->ResetDpi(GetLogicalDpi()); - - mswr::ComPtr<wingfx::Printing::IPrintDocumentSource> print_source; - hr = print_document_source.As(&print_source); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to cast document Source " << std::hex << hr; - return hr; - } - - hr = args->SetSource(print_source.Get()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to set document Source " << std::hex << hr; - return hr; - } - - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::SetPrintDocumentSource, - print_document_source)); - - return hr; -} - -HRESULT PrintHandler::OnCompleted( - wingfx::Printing::IPrintTask* task, - wingfx::Printing::IPrintTaskCompletedEventArgs* args) { - DVLOG(1) << __FUNCTION__; - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - ClearPrintTask(); - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::ReleasePrintDocumentSource)); - - return S_OK; -} - -void PrintHandler::ClearPrintTask() { - if (!print_task_.Get()) - return; - - HRESULT hr = print_task_->remove_Completed(print_completed_token_); - LOG_IF(ERROR, FAILED(hr)) << "Failed to remove completed event from Task " - << std::hex << hr; - print_task_.Reset(); -} - -float PrintHandler::GetLogicalDpi() { - mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Display_DisplayProperties, - display_properties.GetAddressOf()); - if (FAILED(hr)) { - LOG(ERROR) << "Failed to get display properties " << std::hex << hr; - return 0.0; - } - - FLOAT dpi = 0.0; - hr = display_properties->get_LogicalDpi(&dpi); - LOG_IF(ERROR, FAILED(hr)) << "Failed to get Logical DPI " << std::hex << hr; - - return dpi; -} - -HRESULT PrintHandler::LogicalDpiChanged(IInspectable *sender) { - DVLOG(1) << __FUNCTION__; - thread_->message_loop()->PostTask( - FROM_HERE, - base::Bind(&PrintHandler::OnLogicalDpiChanged, GetLogicalDpi())); - return S_OK; -} - -void PrintHandler::OnLogicalDpiChanged(float dpi) { - DCHECK(base::MessageLoop::current() == thread_->message_loop()); - // No need to protect the access to the static variable, - // since it's set/released in this same thread. - if (current_document_source_.Get() != NULL) - current_document_source_->ResetDpi(dpi); -} - -void PrintHandler::SetPrintDocumentSource( - const mswr::ComPtr<PrintDocumentSource>& print_document_source) { - DCHECK(base::MessageLoop::current() == thread_->message_loop()); - DCHECK(current_document_source_.Get() == NULL); - { - // Protect against the other thread which might try to access it. - base::AutoLock lock(*lock_); - current_document_source_ = print_document_source; - } - // Start generating the images to print. - // TODO(mad): Use a registered message with more information about the print - // request, and at a more appropriate time too, and maybe one page at a time. - ::PostMessageW(globals.host_windows.front().first, - WM_SYSCOMMAND, - IDC_PRINT_TO_DESTINATION, - 0); -} - -void PrintHandler::ReleasePrintDocumentSource() { - DCHECK(base::MessageLoop::current() == thread_->message_loop()); - mswr::ComPtr<PrintDocumentSource> print_document_source; - { - // Must wait for other thread to be done with the pointer first. - base::AutoLock lock(*lock_); - current_document_source_.Swap(print_document_source); - } - // This may happen before we get a chance to set the value. - if (print_document_source.Get() != NULL) - print_document_source->Abort(); -} - -void PrintHandler::OnEnablePrinting(bool printing_enabled) { - DCHECK(base::MessageLoop::current() == thread_->message_loop()); - base::AutoLock lock(*lock_); - printing_enabled_ = printing_enabled; - // Don't abort if we are being disabled since we may be finishing a previous - // print request which was valid and should be finished. We just need to - // prevent any new print requests. And don't assert that we are NOT printing - // if we are becoming enabled since we may be finishing a long print while - // we got disabled and then enabled again... -} - -void PrintHandler::OnSetPageCount(size_t page_count) { - DCHECK(base::MessageLoop::current() == thread_->message_loop()); - // No need to protect the access to the static variable, - // since it's set/released in this same thread. - if (current_document_source_.Get() != NULL) - current_document_source_->SetPageCount(page_count); -} - -void PrintHandler::OnAddPage(size_t page_number, - mswr::ComPtr<IStream> metafile_stream) { - DCHECK(base::MessageLoop::current() == thread_->message_loop()); - // No need to protect the access to the static variable, - // since it's set/released in this same thread. - if (current_document_source_.Get() != NULL) - current_document_source_->AddPage(page_number, metafile_stream.Get()); -} - -void PrintHandler::OnShowPrintUI() { - DCHECK(globals.appview_msg_loop->BelongsToCurrentThread()); - mswr::ComPtr<wingfx::Printing::IPrintManagerStatic> print_mgr_static; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Graphics_Printing_PrintManager, - print_mgr_static.GetAddressOf()); - if (SUCCEEDED(hr)) { - DCHECK(print_mgr_static.Get() != NULL); - // Note that passing NULL to ShowPrintUIAsync crashes, - // so we need to setup a temp pointer. - mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> unused_async_op; - hr = print_mgr_static->ShowPrintUIAsync(unused_async_op.GetAddressOf()); - LOG_IF(ERROR, FAILED(hr)) << "Failed to ShowPrintUIAsync " - << std::hex << std::showbase << hr; - } else { - LOG(ERROR) << "Failed to create PrintManagerStatic " - << std::hex << std::showbase << hr; - } -} - -} // namespace metro_driver - -void MetroEnablePrinting(BOOL printing_enabled) { - metro_driver::PrintHandler::EnablePrinting(!!printing_enabled); -} - -void MetroSetPrintPageCount(size_t page_count) { - DVLOG(1) << __FUNCTION__ << " Page count: " << page_count; - metro_driver::PrintHandler::SetPageCount(page_count); -} - -void MetroSetPrintPageContent(size_t page_number, - void* data, - size_t data_size) { - DVLOG(1) << __FUNCTION__ << " Page number: " << page_number; - DCHECK(data != NULL); - DCHECK(data_size > 0); - mswr::ComPtr<IStream> metafile_stream; - HRESULT hr = ::CreateStreamOnHGlobal( - NULL, TRUE, metafile_stream.GetAddressOf()); - if (metafile_stream.Get() != NULL) { - ULONG bytes_written = 0; - hr = metafile_stream->Write(data, - base::checked_cast<ULONG>(data_size), - &bytes_written); - LOG_IF(ERROR, FAILED(hr)) << "Failed to Write to Stream " << std::hex << hr; - DCHECK(bytes_written == data_size); - - metro_driver::PrintHandler::AddPage(page_number, metafile_stream.Get()); - } else { - NOTREACHED() << "Failed to CreateStreamOnHGlobal " << std::hex << hr; - } -} - -void MetroShowPrintUI() { - metro_driver::PrintHandler::ShowPrintUI(); -} diff --git a/win8/metro_driver/print_handler.h b/win8/metro_driver/print_handler.h deleted file mode 100644 index 0fe5719..0000000 --- a/win8/metro_driver/print_handler.h +++ /dev/null @@ -1,117 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_PRINT_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_PRINT_HANDLER_H_ - -#include <windows.media.playto.h> -#include <stddef.h> -#include <windows.graphics.printing.h> -#include <windows.ui.core.h> - -#include "base/synchronization/lock.h" -#include "base/threading/thread.h" -#include "win8/metro_driver/print_document_source.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace base { - -class Lock; - -} // namespace base - -namespace metro_driver { - -// This class handles the print aspect of the devices charm. -class PrintHandler { - public: - PrintHandler(); - ~PrintHandler(); - - HRESULT Initialize(winui::Core::ICoreWindow* window); - - // Called by the exported C functions. - static void EnablePrinting(bool printing_enabled); - static void SetPageCount(size_t page_count); - static void AddPage(size_t page_number, IStream* metafile_stream); - static void ShowPrintUI(); - - private: - // Callbacks from Metro. - HRESULT OnPrintRequested( - wingfx::Printing::IPrintManager* print_mgr, - wingfx::Printing::IPrintTaskRequestedEventArgs* event_args); - - HRESULT OnPrintTaskSourceRequest( - wingfx::Printing::IPrintTaskSourceRequestedArgs* args); - - HRESULT OnCompleted(wingfx::Printing::IPrintTask* task, - wingfx::Printing::IPrintTaskCompletedEventArgs* args); - // Utility methods. - void ClearPrintTask(); - float GetLogicalDpi(); - - // Callback from Metro and entry point called on lockable thread. - HRESULT LogicalDpiChanged(IInspectable *sender); - static void OnLogicalDpiChanged(float dpi); - - // Called on the lockable thread to set/release the doc. - static void SetPrintDocumentSource( - const mswr::ComPtr<PrintDocumentSource>& print_document_source); - static void ReleasePrintDocumentSource(); - - // Called on the lockable thread for the exported C functions. - static void OnEnablePrinting(bool printing_enabled); - static void OnSetPageCount(size_t page_count); - static void OnAddPage(size_t page_number, - mswr::ComPtr<IStream> metafile_stream); - - // Opens the prit device charm. Must be called from the metro thread. - static void OnShowPrintUI(); - - mswr::ComPtr<wingfx::Printing::IPrintTask> print_task_; - EventRegistrationToken print_requested_token_; - EventRegistrationToken print_completed_token_; - EventRegistrationToken dpi_change_token_; - - mswr::ComPtr<wingfx::Printing::IPrintManager> print_manager_; - PrintDocumentSource::DirectXContext directx_context_; - - // Hack to give access to the Print Document from the C style entry points. - // This will go away once we can pass a pointer to this interface down to - // the Chrome Browser as we send the command to print. - static mswr::ComPtr<PrintDocumentSource> current_document_source_; - - // Another hack to enable/disable printing from an exported C function. - // TODO(mad): Find a better way to do this... - static bool printing_enabled_; - - // This is also a temporary hack until we can pass down the print document - // to Chrome so it can call directly into it. We need to lock the access to - // current_document_source_. - static base::Lock* lock_; - - // This thread is used to send blocking jobs - // out of threads we don't want to block. - static base::Thread* thread_; -}; - -} // namespace metro_driver - -// Exported C functions for Chrome to call into the Metro module. -extern "C" __declspec(dllexport) -void MetroEnablePrinting(BOOL printing_enabled); - -extern "C" __declspec(dllexport) -void MetroSetPrintPageCount(size_t page_count); - -extern "C" __declspec(dllexport) -void MetroSetPrintPageContent(size_t current_page, - void* data, - size_t data_size); - -extern "C" __declspec(dllexport) -void MetroShowPrintUI(); - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_PRINT_HANDLER_H_ diff --git a/win8/metro_driver/run_all_unittests.cc b/win8/metro_driver/run_all_unittests.cc deleted file mode 100644 index 4c6a548..0000000 --- a/win8/metro_driver/run_all_unittests.cc +++ /dev/null @@ -1,19 +0,0 @@ -// 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 "stdafx.h" - -#include "base/at_exit.h" -#include "testing/gtest/include/gtest/gtest.h" - -#pragma comment(lib, "runtimeobject.lib") - -base::AtExitManager at_exit; - -int main(int argc, char** argv) { - mswrw::RoInitializeWrapper ro_init(RO_INIT_SINGLETHREADED); - - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/win8/metro_driver/secondary_tile.cc b/win8/metro_driver/secondary_tile.cc deleted file mode 100644 index f04aacc..0000000 --- a/win8/metro_driver/secondary_tile.cc +++ /dev/null @@ -1,229 +0,0 @@ -// 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 "stdafx.h" -#include "secondary_tile.h" - -#include <windows.ui.startscreen.h> - -#include "base/bind.h" -#include "base/logging.h" -#include "base/strings/utf_string_conversions.h" -#include "url/gurl.h" -#include "win8/metro_driver/chrome_app_view.h" -#include "win8/metro_driver/winrt_utils.h" - -namespace { - -using base::win::MetroPinUmaResultCallback; - -// Callback for asynchronous pin requests. -class TileRequestCompleter { - public: - enum PinType { - PIN, - UNPIN - }; - TileRequestCompleter(PinType type, const MetroPinUmaResultCallback& callback) - : type_(type), callback_(callback) {} - - void Complete(mswr::ComPtr<winfoundtn::IAsyncOperation<bool>>& completion); - - private: - // Callback that responds to user input on the pin request pop-up. This will - // run |callback_|, then delete |this| before returning. - HRESULT Respond(winfoundtn::IAsyncOperation<bool>* async, - AsyncStatus status); - - PinType type_; - MetroPinUmaResultCallback callback_; -}; - -void TileRequestCompleter::Complete( - mswr::ComPtr<winfoundtn::IAsyncOperation<bool>>& completion) { - typedef winfoundtn::IAsyncOperationCompletedHandler<bool> RequestDoneType; - mswr::ComPtr<RequestDoneType> handler(mswr::Callback<RequestDoneType>( - this, &TileRequestCompleter::Respond)); - DCHECK(handler.Get() != NULL); - HRESULT hr = completion->put_Completed(handler.Get()); - CheckHR(hr, "Failed to put_Completed"); -} - -HRESULT TileRequestCompleter::Respond(winfoundtn::IAsyncOperation<bool>* async, - AsyncStatus status) { - base::win::MetroSecondaryTilePinUmaResult pin_state = - base::win::METRO_PIN_STATE_NONE; - - if (status == Completed) { - unsigned char result; - CheckHR(async->GetResults(&result)); - LOG(INFO) << __FUNCTION__ << " result " << static_cast<int>(result); - switch (result) { - case 0: - pin_state = type_ == PIN ? - base::win::METRO_PIN_RESULT_CANCEL : - base::win::METRO_UNPIN_RESULT_CANCEL; - break; - case 1: - pin_state = type_ == PIN ? - base::win::METRO_PIN_RESULT_OK : - base::win::METRO_UNPIN_RESULT_OK; - break; - default: - pin_state = type_ == PIN ? - base::win::METRO_PIN_RESULT_OTHER : - base::win::METRO_UNPIN_RESULT_OTHER; - break; - } - } else { - LOG(ERROR) << __FUNCTION__ << " Unexpected async status " - << static_cast<int>(status); - pin_state = type_ == PIN ? - base::win::METRO_PIN_RESULT_ERROR : - base::win::METRO_UNPIN_RESULT_ERROR; - } - callback_.Run(pin_state); - - delete this; - return S_OK; -} - -void DeleteTileFromStartScreen(const base::string16& tile_id, - const MetroPinUmaResultCallback& callback) { - DVLOG(1) << __FUNCTION__; - mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_StartScreen_SecondaryTile, - tile_factory.GetAddressOf()); - CheckHR(hr, "Failed to create instance of ISecondaryTileFactory"); - - mswrw::HString id; - id.Attach(MakeHString(tile_id)); - - mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile; - hr = tile_factory->CreateWithId(id.Get(), tile.GetAddressOf()); - CheckHR(hr, "Failed to create tile"); - - mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> completion; - hr = tile->RequestDeleteAsync(completion.GetAddressOf()); - CheckHR(hr, "RequestDeleteAsync failed"); - - if (FAILED(hr)) { - callback.Run(base::win::METRO_UNPIN_REQUEST_SHOW_ERROR); - return; - } - - // Deleted in TileRequestCompleter::Respond when the async operation - // completes. - TileRequestCompleter* completer = - new TileRequestCompleter(TileRequestCompleter::UNPIN, callback); - completer->Complete(completion); -} - -void CreateTileOnStartScreen(const base::string16& tile_id, - const base::string16& title_str, - const base::string16& url_str, - const base::FilePath& logo_path, - const MetroPinUmaResultCallback& callback) { - VLOG(1) << __FUNCTION__; - - mswr::ComPtr<winui::StartScreen::ISecondaryTileFactory> tile_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_StartScreen_SecondaryTile, - tile_factory.GetAddressOf()); - CheckHR(hr, "Failed to create instance of ISecondaryTileFactory"); - - winui::StartScreen::TileOptions options = - winui::StartScreen::TileOptions_ShowNameOnLogo; - mswrw::HString title; - title.Attach(MakeHString(title_str)); - - mswrw::HString id; - id.Attach(MakeHString(tile_id)); - - mswrw::HString args; - // The url is just passed into the tile agruments as is. Metro and desktop - // chrome will see the arguments as command line parameters. - // A GURL is used to ensure any spaces are properly escaped. - GURL url(url_str); - args.Attach(MakeHString(base::UTF8ToUTF16(url.spec()))); - - mswr::ComPtr<winfoundtn::IUriRuntimeClassFactory> uri_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_Foundation_Uri, - uri_factory.GetAddressOf()); - CheckHR(hr, "Failed to create URIFactory"); - - mswrw::HString logo_url; - logo_url.Attach( - MakeHString(base::string16(L"file:///").append(logo_path.value()))); - mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; - hr = uri_factory->CreateUri(logo_url.Get(), &uri); - CheckHR(hr, "Failed to create URI"); - - mswr::ComPtr<winui::StartScreen::ISecondaryTile> tile; - hr = tile_factory->CreateTile(id.Get(), - title.Get(), - title.Get(), - args.Get(), - options, - uri.Get(), - tile.GetAddressOf()); - CheckHR(hr, "Failed to create tile"); - - hr = tile->put_ForegroundText(winui::StartScreen::ForegroundText_Light); - CheckHR(hr, "Failed to change foreground text color"); - - mswr::ComPtr<winfoundtn::IAsyncOperation<bool>> completion; - hr = tile->RequestCreateAsync(completion.GetAddressOf()); - CheckHR(hr, "RequestCreateAsync failed"); - - if (FAILED(hr)) { - callback.Run(base::win::METRO_PIN_REQUEST_SHOW_ERROR); - return; - } - - // Deleted in TileRequestCompleter::Respond when the async operation - // completes. - TileRequestCompleter* completer = - new TileRequestCompleter(TileRequestCompleter::PIN, callback); - completer->Complete(completion); -} - -} // namespace - -BOOL MetroIsPinnedToStartScreen(const base::string16& tile_id) { - mswr::ComPtr<winui::StartScreen::ISecondaryTileStatics> tile_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_StartScreen_SecondaryTile, - tile_statics.GetAddressOf()); - CheckHR(hr, "Failed to create instance of ISecondaryTileStatics"); - - boolean exists; - hr = tile_statics->Exists(MakeHString(tile_id), &exists); - CheckHR(hr, "ISecondaryTileStatics.Exists failed"); - return exists; -} - -void MetroUnPinFromStartScreen(const base::string16& tile_id, - const MetroPinUmaResultCallback& callback) { - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&DeleteTileFromStartScreen, - tile_id, - callback)); -} - -void MetroPinToStartScreen(const base::string16& tile_id, - const base::string16& title, - const base::string16& url, - const base::FilePath& logo_path, - const MetroPinUmaResultCallback& callback) { - globals.appview_msg_loop->PostTask( - FROM_HERE, base::Bind(&CreateTileOnStartScreen, - tile_id, - title, - url, - logo_path, - callback)); -} diff --git a/win8/metro_driver/secondary_tile.h b/win8/metro_driver/secondary_tile.h deleted file mode 100644 index 1166e13..0000000 --- a/win8/metro_driver/secondary_tile.h +++ /dev/null @@ -1,27 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_SECONDARY_TILE_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_SECONDARY_TILE_H_ - -#include "base/files/file_path.h" -#include "base/strings/string16.h" -#include "base/win/metro.h" - -extern "C" __declspec(dllexport) -BOOL MetroIsPinnedToStartScreen(const base::string16& tile_id); - -extern "C" __declspec(dllexport) -void MetroUnPinFromStartScreen( - const base::string16& tile_id, - const base::win::MetroPinUmaResultCallback& callback); - -extern "C" __declspec(dllexport) -void MetroPinToStartScreen( - const base::string16& tile_id, - const base::string16& title, - const base::string16& url, - const base::FilePath& logo_path, - const base::win::MetroPinUmaResultCallback& callback); - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_SECONDARY_TILE_H_ diff --git a/win8/metro_driver/settings_handler.cc b/win8/metro_driver/settings_handler.cc deleted file mode 100644 index 6feae24..0000000 --- a/win8/metro_driver/settings_handler.cc +++ /dev/null @@ -1,175 +0,0 @@ -// 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 "stdafx.h" -#include "settings_handler.h" - -// This include allows to send WM_SYSCOMMANDs to chrome. -#include "chrome/app/chrome_command_ids.h" -#include "chrome_app_view.h" -#include "winrt_utils.h" - -typedef winfoundtn::ITypedEventHandler< - winui::ApplicationSettings::SettingsPane*, - winui::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs*> - CommandsRequestedHandler; - -namespace { - -// String identifiers for the settings pane commands. -const wchar_t* kSettingsId = L"settings"; -const wchar_t* kHelpId = L"help"; -const wchar_t* kAboutId = L"about"; - -} - -SettingsHandler::SettingsHandler() { - DVLOG(1) << __FUNCTION__; -} - -SettingsHandler::~SettingsHandler() { - DVLOG(1) << __FUNCTION__; -} - -HRESULT SettingsHandler::Initialize() { - mswr::ComPtr<winui::ApplicationSettings::ISettingsPaneStatics> - settings_pane_statics; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ApplicationSettings_SettingsPane, - settings_pane_statics.GetAddressOf()); - CheckHR(hr, "Failed to activate ISettingsPaneStatics"); - - mswr::ComPtr<winui::ApplicationSettings::ISettingsPane> settings_pane; - hr = settings_pane_statics->GetForCurrentView(&settings_pane); - CheckHR(hr, "Failed to get ISettingsPane"); - - hr = settings_pane->add_CommandsRequested( - mswr::Callback<CommandsRequestedHandler>( - this, - &SettingsHandler::OnSettingsCommandsRequested).Get(), - &settings_token_); - CheckHR(hr, "Failed to add CommandsRequested"); - - return hr; -} - -HRESULT SettingsHandler::OnSettingsCommandsRequested( - winui::ApplicationSettings::ISettingsPane* settings_pane, - winui::ApplicationSettings::ISettingsPaneCommandsRequestedEventArgs* args) { - mswr::ComPtr<winui::ApplicationSettings::ISettingsCommandFactory> - settings_command_factory; - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_ApplicationSettings_SettingsCommand, - settings_command_factory.GetAddressOf()); - CheckHR(hr, "Failed to activate ISettingsCommandFactory"); - - mswr::ComPtr<winui::ApplicationSettings::ISettingsPaneCommandsRequest> - settings_command_request; - hr = args->get_Request(&settings_command_request); - CheckHR(hr, "Failed to get_Request"); - - mswr::ComPtr<SettingsHandler::ISettingsCommandVector> application_commands; - hr = settings_command_request->get_ApplicationCommands(&application_commands); - CheckHR(hr, "Failed to get_ApplicationCommands"); - - // TODO(mad): Internationalize the hard coded user visible strings. - hr = AppendNewSettingsCommand( - kSettingsId, L"Settings", settings_command_factory.Get(), - application_commands.Get()); - CheckHR(hr, "Failed to append new settings command"); - - hr = AppendNewSettingsCommand( - kHelpId, L"Help", settings_command_factory.Get(), - application_commands.Get()); - CheckHR(hr, "Failed to append new help command"); - - hr = AppendNewSettingsCommand( - kAboutId, L"About", settings_command_factory.Get(), - application_commands.Get()); - CheckHR(hr, "Failed to append new about command"); - - return hr; -} - -HRESULT SettingsHandler::AppendNewSettingsCommand( - const wchar_t* id, - const wchar_t* name, - winui::ApplicationSettings::ISettingsCommandFactory* - settings_command_factory, - SettingsHandler::ISettingsCommandVector* settings_command_vector) { - mswr::ComPtr<winfoundtn::IPropertyValue> settings_id; - HRESULT hr = GetSettingsId(id, &settings_id); - CheckHR(hr, "Can't get settings id"); - - mswrw::HString settings_name; - settings_name.Attach(MakeHString(name)); - mswr::ComPtr<winui::Popups::IUICommand> command; - hr = settings_command_factory->CreateSettingsCommand( - settings_id.Get(), - settings_name.Get(), - mswr::Callback<winui::Popups::IUICommandInvokedHandler>( - &SettingsHandler::OnSettings).Get(), - command.GetAddressOf()); - CheckHR(hr, "Can't create settings command"); - - hr = settings_command_vector->Append(command.Get()); - CheckHR(hr, "Failed to append settings command"); - - return hr; -} - -HRESULT SettingsHandler::OnSettings(winui::Popups::IUICommand* command) { - mswr::ComPtr<winfoundtn::IPropertyValue> settings_id; - HRESULT hr = GetSettingsId(kSettingsId, &settings_id); - CheckHR(hr, "Failed to get settings id"); - - mswr::ComPtr<winfoundtn::IPropertyValue> help_id; - hr = GetSettingsId(kHelpId, &help_id); - CheckHR(hr, "Failed to get settings id"); - - mswr::ComPtr<winfoundtn::IPropertyValue> about_id; - hr = GetSettingsId(kAboutId, &about_id); - CheckHR(hr, "Failed to get settings id"); - - mswr::ComPtr<winfoundtn::IPropertyValue> command_id; - hr = command->get_Id(&command_id); - CheckHR(hr, "Failed to get command id"); - - INT32 result = -1; - hr = winrt_utils::CompareProperties( - command_id.Get(), settings_id.Get(), &result); - CheckHR(hr, "Failed to compare ids"); - - HWND chrome_window = globals.host_windows.front().first; - - if (result == 0) { - ::PostMessageW(chrome_window, WM_SYSCOMMAND, IDC_OPTIONS, 0); - return S_OK; - } - - hr = winrt_utils::CompareProperties(command_id.Get(), help_id.Get(), &result); - CheckHR(hr, "Failed to compare ids"); - if (result == 0) { - ::PostMessageW(chrome_window, WM_SYSCOMMAND, IDC_HELP_PAGE_VIA_MENU, 0); - return S_OK; - } - - hr = winrt_utils::CompareProperties( - command_id.Get(), about_id.Get(), &result); - CheckHR(hr, "Failed to compare ids"); - if (result == 0) { - ::PostMessageW(chrome_window, WM_SYSCOMMAND, IDC_ABOUT, 0); - return S_OK; - } - - return S_OK; -} - -HRESULT SettingsHandler::GetSettingsId( - const wchar_t* value, winfoundtn::IPropertyValue** settings_id) { - mswrw::HString property_value_string; - property_value_string.Attach(MakeHString(value)); - return winrt_utils::CreateStringProperty(property_value_string.Get(), - settings_id); -} diff --git a/win8/metro_driver/settings_handler.h b/win8/metro_driver/settings_handler.h deleted file mode 100644 index 5b234ad..0000000 --- a/win8/metro_driver/settings_handler.h +++ /dev/null @@ -1,44 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_SETTINGS_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_SETTINGS_HANDLER_H_ - -#include <windows.ui.applicationsettings.h> -#include <windows.ui.popups.h> - -#include "winrt_utils.h" - -// This class handles the settings charm. -class SettingsHandler { - public: - SettingsHandler(); - ~SettingsHandler(); - - HRESULT Initialize(); - - private: - typedef winfoundtn::Collections::IVector< - winui::ApplicationSettings::SettingsCommand*> ISettingsCommandVector; - - HRESULT OnSettingsCommandsRequested( - winui::ApplicationSettings::ISettingsPane* settings_pane, - winui::ApplicationSettings:: - ISettingsPaneCommandsRequestedEventArgs* args); - - HRESULT AppendNewSettingsCommand( - const wchar_t* id, - const wchar_t* name, - winui::ApplicationSettings::ISettingsCommandFactory* - settings_command_factory, - ISettingsCommandVector* settings_command_vector); - - static HRESULT OnSettings(winui::Popups::IUICommand* command); - static HRESULT GetSettingsId(const wchar_t* value, - winfoundtn::IPropertyValue** settings_id); - - EventRegistrationToken settings_token_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_SETTINGS_HANDLER_H_ diff --git a/win8/metro_driver/stdafx.h b/win8/metro_driver/stdafx.h deleted file mode 100644 index 1ce382c..0000000 --- a/win8/metro_driver/stdafx.h +++ /dev/null @@ -1,40 +0,0 @@ -// 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_STDAFX_H_ -#define WIN8_METRO_DRIVER_STDAFX_H_ - -#include <wrl\implements.h> -#include <wrl\module.h> -#include <wrl\event.h> -#include <wrl\wrappers\corewrappers.h> - -#include <activation.h> -#include <d2d1_1.h> -#include <d3d11_1.h> -#include <roapi.h> -#include <stdio.h> -#include <wincodec.h> -#include <windows.h> - -#include <windows.applicationmodel.core.h> -#include <windows.applicationModel.datatransfer.h> -#include <windows.graphics.printing.h> -#include <windows.storage.pickers.h> -#include <windows.ui.notifications.h> - -namespace mswr = Microsoft::WRL; -namespace mswrw = Microsoft::WRL::Wrappers; - -namespace winapp = ABI::Windows::ApplicationModel; -namespace windata = ABI::Windows::Data; -namespace winxml = ABI::Windows::Data::Xml; -namespace windevs = ABI::Windows::Devices; -namespace winfoundtn = ABI::Windows::Foundation; -namespace wingfx = ABI::Windows::Graphics; -namespace winui = ABI::Windows::UI; -namespace winsys = ABI::Windows::System; -namespace winstorage = ABI::Windows::Storage; - -#endif // WIN8_METRO_DRIVER_STDAFX_H_ diff --git a/win8/metro_driver/toast_notification_handler.cc b/win8/metro_driver/toast_notification_handler.cc deleted file mode 100644 index fb44b11..0000000 --- a/win8/metro_driver/toast_notification_handler.cc +++ /dev/null @@ -1,253 +0,0 @@ -// 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 <string> - -#include "win8/metro_driver/stdafx.h" -#include "win8/metro_driver/toast_notification_handler.h" - -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/path_service.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/installer/util/browser_distribution.h" -#include "chrome/installer/util/install_util.h" -#include "chrome/installer/util/shell_util.h" - -#include "win8/metro_driver/winrt_utils.h" - -typedef winfoundtn::ITypedEventHandler< - winui::Notifications::ToastNotification*, IInspectable*> - ToastActivationHandler; - -typedef winfoundtn::ITypedEventHandler< - winui::Notifications::ToastNotification*, - winui::Notifications::ToastDismissedEventArgs*> ToastDismissedHandler; - -namespace { - -// Helper function to return the text node root identified by the index passed -// in. -HRESULT GetTextNodeRoot( - unsigned int index, - winxml::Dom::IXmlDocument* xml_doc, - winxml::Dom::IXmlNode** node) { - DCHECK(xml_doc); - DCHECK(node); - - mswr::ComPtr<winxml::Dom::IXmlElement> document_element; - HRESULT hr = xml_doc->get_DocumentElement(&document_element); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNodeList> elements; - mswrw::HString tag_name; - tag_name.Attach(MakeHString(L"text")); - hr = document_element->GetElementsByTagName(tag_name.Get(), - &elements); - CheckHR(hr); - - unsigned int count = 0; - elements->get_Length(&count); - - if (index > count) { - DVLOG(1) << "Invalid text node index passed in : " << index; - return E_FAIL; - } - hr = elements->Item(index, node); - CheckHR(hr); - return hr; -} - -// Helper function to append a text element to the text section in the -// XML document passed in. -// The index parameter identifies which text node we append to. -HRESULT CreateTextNode(winxml::Dom::IXmlDocument* xml_doc, - int index, - const base::string16& text_string) { - DCHECK(xml_doc); - - mswr::ComPtr<winxml::Dom::IXmlElement> document_element; - HRESULT hr = xml_doc->get_DocumentElement(&document_element); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlText> xml_text_node; - mswrw::HString data_hstring; - data_hstring.Attach(MakeHString(text_string.c_str())); - hr = xml_doc->CreateTextNode(data_hstring.Get(), &xml_text_node); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNode> created_node; - hr = xml_text_node.CopyTo( - winxml::Dom::IID_IXmlNode, - reinterpret_cast<void**>(created_node.GetAddressOf())); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNode> text_node_root; - hr = GetTextNodeRoot(index, xml_doc, &text_node_root); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlNode> appended_node; - hr = text_node_root->AppendChild(created_node.Get(), &appended_node); - CheckHR(hr); - return hr; -} - -} // namespace - -ToastNotificationHandler::DesktopNotification::DesktopNotification( - const char* notification_origin, - const char* notification_icon, - const wchar_t* notification_title, - const wchar_t* notification_body, - const wchar_t* notification_display_source, - const char* notification_id, - base::win::MetroNotificationClickedHandler handler, - const wchar_t* handler_context) - : origin_url(notification_origin), - icon_url(notification_icon), - title(notification_title), - body(notification_body), - display_source(notification_display_source), - id(notification_id), - notification_handler(handler) { - if (handler_context) - notification_context = handler_context; -} - -ToastNotificationHandler::DesktopNotification::DesktopNotification() - : notification_handler(NULL) { -} - -ToastNotificationHandler::ToastNotificationHandler() { - DVLOG(1) << __FUNCTION__; -} - -ToastNotificationHandler::~ToastNotificationHandler() { - DVLOG(1) << __FUNCTION__; - - if (notifier_ && notification_) - CancelNotification(); -} - -void ToastNotificationHandler::DisplayNotification( - const DesktopNotification& notification) { - DVLOG(1) << __FUNCTION__; - - DCHECK(notifier_.Get() == NULL); - DCHECK(notification_.Get() == NULL); - - notification_info_ = notification; - - mswr::ComPtr<winui::Notifications::IToastNotificationManagerStatics> - toast_manager; - - HRESULT hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Notifications_ToastNotificationManager, - toast_manager.GetAddressOf()); - CheckHR(hr); - - mswr::ComPtr<winxml::Dom::IXmlDocument> toast_xml; - hr = toast_manager->GetTemplateContent( - winui::Notifications::ToastTemplateType_ToastText02, - &toast_xml); - CheckHR(hr); - - if (!toast_xml) - return; - - mswr::ComPtr<winxml::Dom::IXmlElement> document_element; - hr = toast_xml->get_DocumentElement(&document_element); - CheckHR(hr); - - if (!document_element) - return; - - hr = CreateTextNode(toast_xml.Get(), 0, notification.title); - CheckHR(hr); - - hr = CreateTextNode(toast_xml.Get(), 1, notification.body); - CheckHR(hr); - - mswrw::HString duration_attribute_name; - duration_attribute_name.Attach(MakeHString(L"duration")); - mswrw::HString duration_attribute_value; - duration_attribute_value.Attach(MakeHString(L"long")); - - hr = document_element->SetAttribute(duration_attribute_name.Get(), - duration_attribute_value.Get()); - CheckHR(hr); - - // TODO(ananta) - // We should set the image and launch params attribute in the notification - // XNL as described here: http://msdn.microsoft.com/en-us/library/hh465448 - // To set the image we may have to extract the image and specify it in the - // following url form. ms-appx:///images/foo.png - // The launch params as described don't get passed back to us via the - // winapp::Activation::ILaunchActivatedEventArgs argument. Needs to be - // investigated. - mswr::ComPtr<winui::Notifications::IToastNotificationFactory> - toast_notification_factory; - hr = winrt_utils::CreateActivationFactory( - RuntimeClass_Windows_UI_Notifications_ToastNotification, - toast_notification_factory.GetAddressOf()); - CheckHR(hr); - - hr = toast_notification_factory->CreateToastNotification( - toast_xml.Get(), ¬ification_); - CheckHR(hr); - - base::FilePath chrome_path; - if (!PathService::Get(base::FILE_EXE, &chrome_path)) { - NOTREACHED() << "Failed to get chrome exe path"; - return; - } - - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - bool is_per_user_install = InstallUtil::IsPerUserInstall( - chrome_path.value().c_str()); - base::string16 appid = - ShellUtil::GetBrowserModelId(dist, is_per_user_install); - DVLOG(1) << "Chrome Appid is " << appid.c_str(); - - mswrw::HString app_user_model_id; - app_user_model_id.Attach(MakeHString(appid)); - - hr = toast_manager->CreateToastNotifierWithId(app_user_model_id.Get(), - ¬ifier_); - CheckHR(hr); - - hr = notification_->add_Activated( - mswr::Callback<ToastActivationHandler>( - this, &ToastNotificationHandler::OnActivate).Get(), - &activated_token_); - CheckHR(hr); - - hr = notifier_->Show(notification_.Get()); - CheckHR(hr); -} - -void ToastNotificationHandler::CancelNotification() { - DVLOG(1) << __FUNCTION__; - - DCHECK(notifier_); - DCHECK(notification_); - - notifier_->Hide(notification_.Get()); -} - -HRESULT ToastNotificationHandler::OnActivate( - winui::Notifications::IToastNotification* notification, - IInspectable* inspectable) { - // TODO(ananta) - // We should pass back information from the notification like the source url - // etc to ChromeAppView which would enable it to ensure that the - // correct tab in chrome is activated. - DVLOG(1) << __FUNCTION__; - - if (notification_info_.notification_handler) { - notification_info_.notification_handler( - notification_info_.notification_context.c_str()); - } - return S_OK; -} diff --git a/win8/metro_driver/toast_notification_handler.h b/win8/metro_driver/toast_notification_handler.h deleted file mode 100644 index f30aee8..0000000 --- a/win8/metro_driver/toast_notification_handler.h +++ /dev/null @@ -1,55 +0,0 @@ -// 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 CHROME_BROWSER_UI_METRO_DRIVER_TOAST_NOTIFICATION_HANDLER_H_ -#define CHROME_BROWSER_UI_METRO_DRIVER_TOAST_NOTIFICATION_HANDLER_H_ - -#include <windows.ui.notifications.h> - -#include "base/strings/string16.h" -#include "base/win/metro.h" - -// Provides functionality to display a metro style toast notification. -class ToastNotificationHandler { - public: - // Holds information about a desktop notification to be displayed. - struct DesktopNotification { - std::string origin_url; - std::string icon_url; - base::string16 title; - base::string16 body; - base::string16 display_source; - std::string id; - base::win::MetroNotificationClickedHandler notification_handler; - base::string16 notification_context; - - DesktopNotification(const char* notification_origin, - const char* notification_icon, - const wchar_t* notification_title, - const wchar_t* notification_body, - const wchar_t* notification_display_source, - const char* notification_id, - base::win::MetroNotificationClickedHandler handler, - const wchar_t* handler_context); - - DesktopNotification(); - }; - - ToastNotificationHandler(); - ~ToastNotificationHandler(); - - void DisplayNotification(const DesktopNotification& notification); - void CancelNotification(); - - HRESULT OnActivate(winui::Notifications::IToastNotification* notification, - IInspectable* inspectable); - - private: - mswr::ComPtr<winui::Notifications::IToastNotifier> notifier_; - mswr::ComPtr<winui::Notifications::IToastNotification> notification_; - EventRegistrationToken activated_token_; - DesktopNotification notification_info_; -}; - -#endif // CHROME_BROWSER_UI_METRO_DRIVER_TOAST_NOTIFICATION_HANDLER_H_ diff --git a/win8/metro_driver/winrt_utils.cc b/win8/metro_driver/winrt_utils.cc deleted file mode 100644 index 4c7dc36..0000000 --- a/win8/metro_driver/winrt_utils.cc +++ /dev/null @@ -1,226 +0,0 @@ -// 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 "stdafx.h" -#include "winrt_utils.h" - -#include <shlobj.h> - -#include "base/files/file_path.h" -#include "base/logging.h" -#include "base/win/scoped_com_initializer.h" -#include "base/win/scoped_comptr.h" -#include "chrome/installer/util/browser_distribution.h" -#include "chrome/installer/util/install_util.h" - -void CheckHR(HRESULT hr, const char* message) { - if (FAILED(hr)) { - if (message) - PLOG(DFATAL) << message << ", hr = " << std::hex << hr; - else - PLOG(DFATAL) << "COM ERROR" << ", hr = " << std::hex << hr; - } -} - -HSTRING MakeHString(const base::string16& str) { - HSTRING hstr; - if (FAILED(::WindowsCreateString(str.c_str(), static_cast<UINT32>(str.size()), - &hstr))) { - PLOG(DFATAL) << "Hstring creation failed"; - } - return hstr; -} - -base::string16 MakeStdWString(HSTRING hstring) { - const wchar_t* str; - UINT32 size = 0; - str = ::WindowsGetStringRawBuffer(hstring, &size); - if (!size) - return base::string16(); - return base::string16(str, size); -} - -namespace { - -#define IMPLEMENT_CREATE_PROPERTY(Name, Type) \ -HRESULT Create ## Name ## Property(Type value, \ - winfoundtn::IPropertyValue** prop) { \ - mswr::ComPtr<winfoundtn::IPropertyValueStatics> property_value_statics; \ - HRESULT hr = winrt_utils::CreateActivationFactory( \ - RuntimeClass_Windows_Foundation_PropertyValue, \ - property_value_statics.GetAddressOf()); \ - CheckHR(hr, "Can't create IPropertyValueStatics"); \ - hr = property_value_statics->Create ## Name ( \ - value, \ - reinterpret_cast<IInspectable**>(prop)); \ - CheckHR(hr, "Failed to create Property"); \ - return hr; \ -} - -#define COMPARE_ATOMIC_PROPERTY_VALUES(Name, Type) \ - Type lhs_value; \ - hr = lhs->Get ## Name (&lhs_value); \ - CheckHR(hr, "Can't get value for lhs"); \ - Type rhs_value; \ - hr = rhs->Get ## Name (&rhs_value); \ - CheckHR(hr, "Can't get value for rhs"); \ - if (lhs_value < rhs_value) \ - *result = -1; \ - else if (lhs_value > rhs_value) \ - *result = 1; \ - else \ - *result = 0; \ - hr = S_OK - -} // namespace - -namespace winrt_utils { - -IMPLEMENT_CREATE_PROPERTY(String, HSTRING); -IMPLEMENT_CREATE_PROPERTY(Int16, INT16); -IMPLEMENT_CREATE_PROPERTY(Int32, INT32); -IMPLEMENT_CREATE_PROPERTY(Int64, INT64); -IMPLEMENT_CREATE_PROPERTY(UInt8, UINT8); -IMPLEMENT_CREATE_PROPERTY(UInt16, UINT16); -IMPLEMENT_CREATE_PROPERTY(UInt32, UINT32); -IMPLEMENT_CREATE_PROPERTY(UInt64, UINT64); - -HRESULT CompareProperties(winfoundtn::IPropertyValue* lhs, - winfoundtn::IPropertyValue* rhs, - INT32* result) { - if (result == nullptr) { - PLOG(DFATAL) << "Invalid argument to CompareProperties."; - return E_INVALIDARG; - } - - if (lhs == rhs) { - *result = 0; - return S_OK; - } - - winfoundtn::PropertyType lhs_property_type; - HRESULT hr = lhs->get_Type(&lhs_property_type); - if (FAILED(hr)) { - PLOG(DFATAL) << "Can't get property type for lhs, hr=" << std::hex << hr; - } - - winfoundtn::PropertyType rhs_property_type; - hr = rhs->get_Type(&rhs_property_type); - CheckHR(hr, "Can't get property type for rhs"); - - if (lhs_property_type != rhs_property_type) - return E_INVALIDARG; - - switch (lhs_property_type) { - case winfoundtn::PropertyType::PropertyType_String: { - mswrw::HString lhs_string; - hr = lhs->GetString(lhs_string.GetAddressOf()); - CheckHR(hr, "Can't get string for lhs"); - - mswrw::HString rhs_string; - hr = rhs->GetString(rhs_string.GetAddressOf()); - CheckHR(hr, "Can't get string for rhs"); - - hr = WindowsCompareStringOrdinal( - lhs_string.Get(), rhs_string.Get(), result); - break; - } - case winfoundtn::PropertyType::PropertyType_Char16: { - COMPARE_ATOMIC_PROPERTY_VALUES(Char16, wchar_t); - break; - } - case winfoundtn::PropertyType::PropertyType_Double: { - COMPARE_ATOMIC_PROPERTY_VALUES(Double, double); - break; - } - case winfoundtn::PropertyType::PropertyType_Int16: { - COMPARE_ATOMIC_PROPERTY_VALUES(Int16, INT16); - break; - } - case winfoundtn::PropertyType::PropertyType_Int32: { - COMPARE_ATOMIC_PROPERTY_VALUES(Int32, INT32); - break; - } - case winfoundtn::PropertyType::PropertyType_Int64: { - COMPARE_ATOMIC_PROPERTY_VALUES(Int64, INT64); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt8: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt8, UINT8); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt16: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt16, UINT16); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt32: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt32, UINT32); - break; - } - case winfoundtn::PropertyType::PropertyType_UInt64: { - COMPARE_ATOMIC_PROPERTY_VALUES(UInt64, UINT64); - break; - } - default: { - hr = E_NOTIMPL; - } - } - return hr; -} - -bool GetArgumentsFromShortcut(const base::FilePath& shortcut, - base::string16* arguments) { - HRESULT result; - base::win::ScopedComPtr<IShellLink> i_shell_link; - bool is_resolved = false; - - - base::win::ScopedCOMInitializer sta_com_initializer; - - // Get pointer to the IShellLink interface - result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER); - if (SUCCEEDED(result)) { - base::win::ScopedComPtr<IPersistFile> persist; - // Query IShellLink for the IPersistFile interface - result = persist.QueryFrom(i_shell_link.get()); - if (SUCCEEDED(result)) { - WCHAR temp_arguments[MAX_PATH]; - // Load the shell link - result = persist->Load(shortcut.value().c_str(), STGM_READ); - if (SUCCEEDED(result)) { - result = i_shell_link->GetArguments(temp_arguments, MAX_PATH); - *arguments = temp_arguments; - is_resolved = true; - } - } - } - - return is_resolved; -} - -base::string16 ReadArgumentsFromPinnedTaskbarShortcut() { - wchar_t path_buffer[MAX_PATH] = {}; - - if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, - SHGFP_TYPE_CURRENT, path_buffer))) { - base::FilePath shortcut(path_buffer); - shortcut = shortcut.Append( - L"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"); - - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - base::string16 link_name = dist->GetShortcutName( - BrowserDistribution::SHORTCUT_CHROME) + installer::kLnkExt; - shortcut = shortcut.Append(link_name); - - base::string16 arguments; - if (GetArgumentsFromShortcut(shortcut, &arguments)) { - return arguments; - } - } - - return L""; -} - -} // namespace winrt_utils diff --git a/win8/metro_driver/winrt_utils.h b/win8/metro_driver/winrt_utils.h deleted file mode 100644 index e3a777f..0000000 --- a/win8/metro_driver/winrt_utils.h +++ /dev/null @@ -1,60 +0,0 @@ -// 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_WINRT_UTILS_H_ -#define WIN8_METRO_DRIVER_WINRT_UTILS_H_ - -#include <string> - -#include <roapi.h> -#include <windows.applicationmodel.core.h> - -#include "base/strings/string16.h" - -void CheckHR(HRESULT hr, const char* str = nullptr); - -HSTRING MakeHString(const base::string16& str); - -base::string16 MakeStdWString(HSTRING hstring); - -namespace winrt_utils { - -template<unsigned int size, typename T> -HRESULT CreateActivationFactory(wchar_t const (&class_name)[size], T** object) { - mswrw::HStringReference ref_class_name(class_name); - return winfoundtn::GetActivationFactory(ref_class_name.Get(), object); -} - -#define DECLARE_CREATE_PROPERTY(Name, Type) \ -HRESULT Create ## Name ## Property( \ - Type value, \ - winfoundtn::IPropertyValue** prop); - -DECLARE_CREATE_PROPERTY(String, HSTRING); -DECLARE_CREATE_PROPERTY(Int16, INT16); -DECLARE_CREATE_PROPERTY(Int32, INT32); -DECLARE_CREATE_PROPERTY(Int64, INT64); -DECLARE_CREATE_PROPERTY(UInt8, UINT8); -DECLARE_CREATE_PROPERTY(UInt16, UINT16); -DECLARE_CREATE_PROPERTY(UInt32, UINT32); -DECLARE_CREATE_PROPERTY(UInt64, UINT64); - -// Compares |lhs| with |rhs| and return the |result| as -// WindowsCompareStringOrdinal would do, i.e., -// -1 if |lhs| is less than |rhs|, 0 if they are equal, and -// +1 if |lhs| is greater than |rhs|. -HRESULT CompareProperties( - winfoundtn::IPropertyValue* lhs, winfoundtn::IPropertyValue* rhs, - INT32* result); - -// Looks for a pinned taskbar shortcut in the current user's profile. If it -// finds one, will return any arguments that have been appended to the -// shortcut's command line. This is intended for scenarios where those shortcut -// parameters are ordinarily ignored (i.e. metro apps on win8). Returns an -// empty string on failure. -base::string16 ReadArgumentsFromPinnedTaskbarShortcut(); - -} // namespace winrt_utils - -#endif // WIN8_METRO_DRIVER_WINRT_UTILS_H_ diff --git a/win8/metro_driver/winrt_utils_unittest.cc b/win8/metro_driver/winrt_utils_unittest.cc deleted file mode 100644 index 6fa1bc7..0000000 --- a/win8/metro_driver/winrt_utils_unittest.cc +++ /dev/null @@ -1,115 +0,0 @@ -// 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 "stdafx.h" - -#include "winrt_utils.h" - -#include "base/logging.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -template <typename Type> -HRESULT CreateProperty(Type value, winfoundtn::IPropertyValue** prop) { - return E_NOTIMPL; -} - -template <> -HRESULT CreateProperty<const wchar_t*>( - const wchar_t* value, winfoundtn::IPropertyValue** prop) { - mswrw::HString string_value; - string_value.Attach(MakeHString(value)); - return winrt_utils::CreateStringProperty(string_value.Get(), prop); -} - -template <> -HRESULT CreateProperty<INT16>(INT16 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateInt16Property(value, prop); -} - -template <> -HRESULT CreateProperty<INT32>(INT32 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateInt32Property(value, prop); -} - -template <> -HRESULT CreateProperty<INT64>(INT64 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateInt64Property(value, prop); -} - -template <> -HRESULT CreateProperty<UINT8>(UINT8 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt8Property(value, prop); -} - -template <> -HRESULT CreateProperty<UINT16>(UINT16 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt16Property(value, prop); -} - -template <> -HRESULT CreateProperty<UINT32>(UINT32 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt32Property(value, prop); -} - -template <> -HRESULT CreateProperty<UINT64>(UINT64 value, - winfoundtn::IPropertyValue** prop) { - return winrt_utils::CreateUInt64Property(value, prop); -} - -template<typename Type> -void TestCompareProperties(Type value1, Type value2) { - mswr::ComPtr<winfoundtn::IPropertyValue> property_1; - HRESULT hr = CreateProperty<Type>(value1, property_1.GetAddressOf()); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't create Property value 1"; - - mswr::ComPtr<winfoundtn::IPropertyValue> other_property_1; - hr = CreateProperty<Type>(value1, other_property_1.GetAddressOf()); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't create another Property value 1"; - - mswr::ComPtr<winfoundtn::IPropertyValue> property_2; - hr = CreateProperty<Type>(value2, property_2.GetAddressOf()); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't create Property value 2"; - - INT32 result = 42; - hr = winrt_utils::CompareProperties( - property_1.Get(), property_1.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to itself"; - EXPECT_EQ(0, result) << "Bad result value while comparing same property"; - - hr = winrt_utils::CompareProperties( - property_1.Get(), other_property_1.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to other_property_1"; - EXPECT_EQ(0, result) << "Bad result while comparing equal values"; - - hr = winrt_utils::CompareProperties( - property_1.Get(), property_2.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to property_2"; - EXPECT_EQ(-1, result) << "Bad result while comparing values for less than"; - - hr = winrt_utils::CompareProperties( - property_2.Get(), property_1.Get(), &result); - ASSERT_TRUE(SUCCEEDED(hr)) << "Can't compare property_1 to property_2"; - EXPECT_EQ(1, result) << "Bad result value while comparing for greater than"; -} - -TEST(PropertyValueCompareTest, CompareProperties) { - TestCompareProperties<INT16>(42, 43); - TestCompareProperties<INT32>(42, 43); - TestCompareProperties<INT64>(42, 43); - TestCompareProperties<UINT8>(42, 43); - TestCompareProperties<UINT16>(42, 43); - TestCompareProperties<UINT32>(42, 43); - TestCompareProperties<UINT64>(42, 43); - TestCompareProperties<const wchar_t*>(L"abc", L"bcd"); -} - -} // namespace |