Home | History | Annotate | Download | only in aura
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/aura/remote_root_window_host_win.h"
      6 
      7 #include <windows.h>
      8 
      9 #include <algorithm>
     10 
     11 #include "base/message_loop/message_loop.h"
     12 #include "ipc/ipc_message.h"
     13 #include "ipc/ipc_sender.h"
     14 #include "ui/aura/client/aura_constants.h"
     15 #include "ui/aura/client/cursor_client.h"
     16 #include "ui/aura/root_window.h"
     17 #include "ui/aura/window_property.h"
     18 #include "ui/base/cursor/cursor_loader_win.h"
     19 #include "ui/base/ime/composition_text.h"
     20 #include "ui/base/ime/input_method.h"
     21 #include "ui/base/ime/remote_input_method_win.h"
     22 #include "ui/base/ime/text_input_client.h"
     23 #include "ui/events/event_utils.h"
     24 #include "ui/events/keycodes/keyboard_code_conversion_win.h"
     25 #include "ui/base/view_prop.h"
     26 #include "ui/gfx/insets.h"
     27 #include "ui/metro_viewer/metro_viewer_messages.h"
     28 
     29 namespace aura {
     30 
     31 namespace {
     32 
     33 const char* kRootWindowHostWinKey = "__AURA_REMOTE_ROOT_WINDOW_HOST_WIN__";
     34 
     35 // Sets the keystate for the virtual key passed in to down or up.
     36 void SetKeyState(uint8* key_states, bool key_down, uint32 virtual_key_code) {
     37   DCHECK(key_states);
     38 
     39   if (key_down)
     40     key_states[virtual_key_code] |= 0x80;
     41   else
     42     key_states[virtual_key_code] &= 0x7F;
     43 }
     44 
     45 // Sets the keyboard states for the Shift/Control/Alt/Caps lock keys.
     46 void SetVirtualKeyStates(uint32 flags) {
     47   uint8 keyboard_state[256] = {0};
     48   ::GetKeyboardState(keyboard_state);
     49 
     50   SetKeyState(keyboard_state, !!(flags & ui::EF_SHIFT_DOWN), VK_SHIFT);
     51   SetKeyState(keyboard_state, !!(flags & ui::EF_CONTROL_DOWN), VK_CONTROL);
     52   SetKeyState(keyboard_state, !!(flags & ui::EF_ALT_DOWN), VK_MENU);
     53   SetKeyState(keyboard_state, !!(flags & ui::EF_CAPS_LOCK_DOWN), VK_CAPITAL);
     54   SetKeyState(keyboard_state, !!(flags & ui::EF_LEFT_MOUSE_BUTTON), VK_LBUTTON);
     55   SetKeyState(keyboard_state, !!(flags & ui::EF_RIGHT_MOUSE_BUTTON),
     56               VK_RBUTTON);
     57   SetKeyState(keyboard_state, !!(flags & ui::EF_MIDDLE_MOUSE_BUTTON),
     58               VK_MBUTTON);
     59 
     60   ::SetKeyboardState(keyboard_state);
     61 }
     62 
     63 void FillCompositionText(
     64     const string16& text,
     65     int32 selection_start,
     66     int32 selection_end,
     67     const std::vector<metro_viewer::UnderlineInfo>& underlines,
     68     ui::CompositionText* composition_text) {
     69   composition_text->Clear();
     70   composition_text->text = text;
     71   composition_text->selection.set_start(selection_start);
     72   composition_text->selection.set_end(selection_end);
     73   composition_text->underlines.resize(underlines.size());
     74   for (size_t i = 0; i < underlines.size(); ++i) {
     75     composition_text->underlines[i].start_offset = underlines[i].start_offset;
     76     composition_text->underlines[i].end_offset = underlines[i].end_offset;
     77     composition_text->underlines[i].color = SK_ColorBLACK;
     78     composition_text->underlines[i].thick = underlines[i].thick;
     79   }
     80 }
     81 
     82 }  // namespace
     83 
     84 void HandleOpenFile(const base::string16& title,
     85                     const base::FilePath& default_path,
     86                     const base::string16& filter,
     87                     const OpenFileCompletion& on_success,
     88                     const FileSelectionCanceled& on_failure) {
     89   DCHECK(aura::RemoteRootWindowHostWin::Instance());
     90   aura::RemoteRootWindowHostWin::Instance()->HandleOpenFile(title,
     91                                                             default_path,
     92                                                             filter,
     93                                                             on_success,
     94                                                             on_failure);
     95 }
     96 
     97 void HandleOpenMultipleFiles(const base::string16& title,
     98                              const base::FilePath& default_path,
     99                              const base::string16& filter,
    100                              const OpenMultipleFilesCompletion& on_success,
    101                              const FileSelectionCanceled& on_failure) {
    102   DCHECK(aura::RemoteRootWindowHostWin::Instance());
    103   aura::RemoteRootWindowHostWin::Instance()->HandleOpenMultipleFiles(
    104       title,
    105       default_path,
    106       filter,
    107       on_success,
    108       on_failure);
    109 }
    110 
    111 void HandleSaveFile(const base::string16& title,
    112                     const base::FilePath& default_path,
    113                     const base::string16& filter,
    114                     int filter_index,
    115                     const base::string16& default_extension,
    116                     const SaveFileCompletion& on_success,
    117                     const FileSelectionCanceled& on_failure) {
    118   DCHECK(aura::RemoteRootWindowHostWin::Instance());
    119   aura::RemoteRootWindowHostWin::Instance()->HandleSaveFile(title,
    120                                                             default_path,
    121                                                             filter,
    122                                                             filter_index,
    123                                                             default_extension,
    124                                                             on_success,
    125                                                             on_failure);
    126 }
    127 
    128 void HandleSelectFolder(const base::string16& title,
    129                         const SelectFolderCompletion& on_success,
    130                         const FileSelectionCanceled& on_failure) {
    131   DCHECK(aura::RemoteRootWindowHostWin::Instance());
    132   aura::RemoteRootWindowHostWin::Instance()->HandleSelectFolder(title,
    133                                                                 on_success,
    134                                                                 on_failure);
    135 }
    136 
    137 void HandleActivateDesktop(const base::FilePath& shortcut,
    138                            bool ash_exit) {
    139   DCHECK(aura::RemoteRootWindowHostWin::Instance());
    140   aura::RemoteRootWindowHostWin::Instance()->HandleActivateDesktop(shortcut,
    141                                                                    ash_exit);
    142 }
    143 
    144 void HandleMetroExit() {
    145   DCHECK(aura::RemoteRootWindowHostWin::Instance());
    146   aura::RemoteRootWindowHostWin::Instance()->HandleMetroExit();
    147 }
    148 
    149 RemoteRootWindowHostWin* g_instance = NULL;
    150 
    151 RemoteRootWindowHostWin* RemoteRootWindowHostWin::Instance() {
    152   if (g_instance)
    153     return g_instance;
    154   return Create(gfx::Rect());
    155 }
    156 
    157 RemoteRootWindowHostWin* RemoteRootWindowHostWin::Create(
    158     const gfx::Rect& bounds) {
    159   g_instance = g_instance ? g_instance : new RemoteRootWindowHostWin(bounds);
    160   return g_instance;
    161 }
    162 
    163 RemoteRootWindowHostWin::RemoteRootWindowHostWin(const gfx::Rect& bounds)
    164     : remote_window_(NULL),
    165       host_(NULL),
    166       ignore_mouse_moves_until_set_cursor_ack_(false),
    167       event_flags_(0),
    168       window_size_(aura::RootWindowHost::GetNativeScreenSize()) {
    169   prop_.reset(new ui::ViewProp(NULL, kRootWindowHostWinKey, this));
    170 }
    171 
    172 RemoteRootWindowHostWin::~RemoteRootWindowHostWin() {
    173   g_instance = NULL;
    174 }
    175 
    176 void RemoteRootWindowHostWin::Connected(IPC::Sender* host, HWND remote_window) {
    177   CHECK(host_ == NULL);
    178   host_ = host;
    179   remote_window_ = remote_window;
    180 }
    181 
    182 void RemoteRootWindowHostWin::Disconnected() {
    183   // Don't CHECK here, Disconnected is called on a channel error which can
    184   // happen before we're successfully Connected.
    185   if (!host_)
    186     return;
    187   ui::RemoteInputMethodPrivateWin* remote_input_method_private =
    188       GetRemoteInputMethodPrivate();
    189   if (remote_input_method_private)
    190     remote_input_method_private->SetRemoteDelegate(NULL);
    191   host_ = NULL;
    192   remote_window_ = NULL;
    193 }
    194 
    195 bool RemoteRootWindowHostWin::OnMessageReceived(const IPC::Message& message) {
    196   bool handled = true;
    197   IPC_BEGIN_MESSAGE_MAP(RemoteRootWindowHostWin, message)
    198     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MouseMoved, OnMouseMoved)
    199     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MouseButton, OnMouseButton)
    200     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_KeyDown, OnKeyDown)
    201     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_KeyUp, OnKeyUp)
    202     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_Character, OnChar)
    203     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_WindowActivated,
    204                         OnWindowActivated)
    205     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_TouchDown,
    206                         OnTouchDown)
    207     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_TouchUp,
    208                         OnTouchUp)
    209     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_TouchMoved,
    210                         OnTouchMoved)
    211     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_FileSaveAsDone,
    212                         OnFileSaveAsDone)
    213     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_FileOpenDone,
    214                         OnFileOpenDone)
    215     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MultiFileOpenDone,
    216                         OnMultiFileOpenDone)
    217     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SelectFolderDone,
    218                         OnSelectFolderDone)
    219     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetCursorPosAck,
    220                         OnSetCursorPosAck)
    221     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeCandidatePopupChanged,
    222                         OnImeCandidatePopupChanged)
    223     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeCompositionChanged,
    224                         OnImeCompositionChanged)
    225     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeTextCommitted,
    226                         OnImeTextCommitted)
    227     IPC_MESSAGE_HANDLER(MetroViewerHostMsg_ImeInputSourceChanged,
    228                         OnImeInputSourceChanged)
    229     IPC_MESSAGE_UNHANDLED(handled = false)
    230   IPC_END_MESSAGE_MAP()
    231   return handled;
    232 }
    233 
    234 void RemoteRootWindowHostWin::HandleOpenURLOnDesktop(
    235     const base::FilePath& shortcut,
    236     const base::string16& url) {
    237   if (!host_)
    238     return;
    239   host_->Send(new MetroViewerHostMsg_OpenURLOnDesktop(shortcut, url));
    240 }
    241 
    242 void RemoteRootWindowHostWin::HandleActivateDesktop(
    243     const base::FilePath& shortcut,
    244     bool ash_exit) {
    245   if (!host_)
    246     return;
    247   host_->Send(new MetroViewerHostMsg_ActivateDesktop(shortcut, ash_exit));
    248 }
    249 
    250 void RemoteRootWindowHostWin::HandleMetroExit() {
    251   if (!host_)
    252     return;
    253   host_->Send(new MetroViewerHostMsg_MetroExit());
    254 }
    255 
    256 void RemoteRootWindowHostWin::HandleOpenFile(
    257     const base::string16& title,
    258     const base::FilePath& default_path,
    259     const base::string16& filter,
    260     const OpenFileCompletion& on_success,
    261     const FileSelectionCanceled& on_failure) {
    262   if (!host_)
    263     return;
    264 
    265   // Can only have one of these operations in flight.
    266   DCHECK(file_open_completion_callback_.is_null());
    267   DCHECK(failure_callback_.is_null());
    268 
    269   file_open_completion_callback_ = on_success;
    270   failure_callback_ = on_failure;
    271 
    272   host_->Send(new MetroViewerHostMsg_DisplayFileOpen(title,
    273                                                      filter,
    274                                                      default_path,
    275                                                      false));
    276 }
    277 
    278 void RemoteRootWindowHostWin::HandleOpenMultipleFiles(
    279     const base::string16& title,
    280     const base::FilePath& default_path,
    281     const base::string16& filter,
    282     const OpenMultipleFilesCompletion& on_success,
    283     const FileSelectionCanceled& on_failure) {
    284   if (!host_)
    285     return;
    286 
    287   // Can only have one of these operations in flight.
    288   DCHECK(multi_file_open_completion_callback_.is_null());
    289   DCHECK(failure_callback_.is_null());
    290   multi_file_open_completion_callback_ = on_success;
    291   failure_callback_ = on_failure;
    292 
    293   host_->Send(new MetroViewerHostMsg_DisplayFileOpen(title,
    294                                                      filter,
    295                                                      default_path,
    296                                                      true));
    297 }
    298 
    299 void RemoteRootWindowHostWin::HandleSaveFile(
    300     const base::string16& title,
    301     const base::FilePath& default_path,
    302     const base::string16& filter,
    303     int filter_index,
    304     const base::string16& default_extension,
    305     const SaveFileCompletion& on_success,
    306     const FileSelectionCanceled& on_failure) {
    307   if (!host_)
    308     return;
    309 
    310   MetroViewerHostMsg_SaveAsDialogParams params;
    311   params.title = title;
    312   params.default_extension = default_extension;
    313   params.filter = filter;
    314   params.filter_index = filter_index;
    315   params.suggested_name = default_path;
    316 
    317   // Can only have one of these operations in flight.
    318   DCHECK(file_saveas_completion_callback_.is_null());
    319   DCHECK(failure_callback_.is_null());
    320   file_saveas_completion_callback_ = on_success;
    321   failure_callback_ = on_failure;
    322 
    323   host_->Send(new MetroViewerHostMsg_DisplayFileSaveAs(params));
    324 }
    325 
    326 void RemoteRootWindowHostWin::HandleSelectFolder(
    327     const base::string16& title,
    328     const SelectFolderCompletion& on_success,
    329     const FileSelectionCanceled& on_failure) {
    330   if (!host_)
    331     return;
    332 
    333   // Can only have one of these operations in flight.
    334   DCHECK(select_folder_completion_callback_.is_null());
    335   DCHECK(failure_callback_.is_null());
    336   select_folder_completion_callback_ = on_success;
    337   failure_callback_ = on_failure;
    338 
    339   host_->Send(new MetroViewerHostMsg_DisplaySelectFolder(title));
    340 }
    341 
    342 void RemoteRootWindowHostWin::HandleWindowSizeChanged(uint32 width,
    343                                                       uint32 height) {
    344   SetBounds(gfx::Rect(0, 0, width, height));
    345 }
    346 
    347 bool RemoteRootWindowHostWin::IsForegroundWindow() {
    348   return ::GetForegroundWindow() == remote_window_;
    349 }
    350 
    351 Window* RemoteRootWindowHostWin::GetAshWindow() {
    352   return GetRootWindow()->window();
    353 }
    354 
    355 RootWindow* RemoteRootWindowHostWin::GetRootWindow() {
    356   return delegate_->AsRootWindow();
    357 }
    358 
    359 gfx::AcceleratedWidget RemoteRootWindowHostWin::GetAcceleratedWidget() {
    360   if (remote_window_)
    361     return remote_window_;
    362   // Getting here should only happen for ash_unittests.exe and related code.
    363   return ::GetDesktopWindow();
    364 }
    365 
    366 void RemoteRootWindowHostWin::Show() {
    367   ui::RemoteInputMethodPrivateWin* remote_input_method_private =
    368       GetRemoteInputMethodPrivate();
    369   if (remote_input_method_private)
    370     remote_input_method_private->SetRemoteDelegate(this);
    371 }
    372 
    373 void RemoteRootWindowHostWin::Hide() {
    374   NOTIMPLEMENTED();
    375 }
    376 
    377 void RemoteRootWindowHostWin::ToggleFullScreen() {
    378 }
    379 
    380 gfx::Rect RemoteRootWindowHostWin::GetBounds() const {
    381   return gfx::Rect(window_size_);
    382 }
    383 
    384 void RemoteRootWindowHostWin::SetBounds(const gfx::Rect& bounds) {
    385   window_size_ = bounds.size();
    386   delegate_->OnHostResized(bounds.size());
    387 }
    388 
    389 gfx::Insets RemoteRootWindowHostWin::GetInsets() const {
    390   return gfx::Insets();
    391 }
    392 
    393 void RemoteRootWindowHostWin::SetInsets(const gfx::Insets& insets) {
    394 }
    395 
    396 gfx::Point RemoteRootWindowHostWin::GetLocationOnNativeScreen() const {
    397   return gfx::Point(0, 0);
    398 }
    399 
    400 void RemoteRootWindowHostWin::SetCursor(gfx::NativeCursor native_cursor) {
    401   if (!host_)
    402     return;
    403   host_->Send(
    404       new MetroViewerHostMsg_SetCursor(uint64(native_cursor.platform())));
    405 }
    406 
    407 void RemoteRootWindowHostWin::SetCapture() {
    408 }
    409 
    410 void RemoteRootWindowHostWin::ReleaseCapture() {
    411 }
    412 
    413 bool RemoteRootWindowHostWin::QueryMouseLocation(gfx::Point* location_return) {
    414   aura::client::CursorClient* cursor_client =
    415       aura::client::GetCursorClient(GetRootWindow()->window());
    416   if (cursor_client && !cursor_client->IsMouseEventsEnabled()) {
    417     *location_return = gfx::Point(0, 0);
    418     return false;
    419   }
    420   POINT pt;
    421   GetCursorPos(&pt);
    422   *location_return =
    423       gfx::Point(static_cast<int>(pt.x), static_cast<int>(pt.y));
    424   return true;
    425 }
    426 
    427 bool RemoteRootWindowHostWin::ConfineCursorToRootWindow() {
    428   return true;
    429 }
    430 
    431 void RemoteRootWindowHostWin::UnConfineCursor() {
    432 }
    433 
    434 void RemoteRootWindowHostWin::OnCursorVisibilityChanged(bool show) {
    435   NOTIMPLEMENTED();
    436 }
    437 
    438 void RemoteRootWindowHostWin::MoveCursorTo(const gfx::Point& location) {
    439   VLOG(1) << "In MoveCursorTo: " << location.x() << ", " << location.y();
    440   if (!host_)
    441     return;
    442 
    443   // This function can be called in cases like when the mouse cursor is
    444   // restricted within a viewport (For e.g. LockCursor) which assumes that
    445   // subsequent mouse moves would be received starting with the new cursor
    446   // coordinates. This is a challenge for Windows ASH for the reasons
    447   // outlined below.
    448   // Other cases which don't expect this behavior should continue to work
    449   // without issues.
    450 
    451   // The mouse events are received by the viewer process and sent to the
    452   // browser. If we invoke the SetCursor API here we continue to receive
    453   // mouse messages from the viewer which were posted before the SetCursor
    454   // API executes which messes up the state in the browser. To workaround
    455   // this we invoke the SetCursor API in the viewer process and ignore
    456   // mouse messages until we received an ACK from the viewer indicating that
    457   // the SetCursor operation completed.
    458   ignore_mouse_moves_until_set_cursor_ack_ = true;
    459   VLOG(1) << "In MoveCursorTo. Sending IPC";
    460   host_->Send(new MetroViewerHostMsg_SetCursorPos(location.x(), location.y()));
    461 }
    462 
    463 void RemoteRootWindowHostWin::PostNativeEvent(
    464     const base::NativeEvent& native_event) {
    465 }
    466 
    467 void RemoteRootWindowHostWin::OnDeviceScaleFactorChanged(
    468     float device_scale_factor) {
    469   NOTIMPLEMENTED();
    470 }
    471 
    472 void RemoteRootWindowHostWin::PrepareForShutdown() {
    473 }
    474 
    475 void RemoteRootWindowHostWin::CancelComposition() {
    476   host_->Send(new MetroViewerHostMsg_ImeCancelComposition);
    477 }
    478 
    479 void RemoteRootWindowHostWin::OnTextInputClientUpdated(
    480     const std::vector<int32>& input_scopes,
    481     const std::vector<gfx::Rect>& composition_character_bounds) {
    482   std::vector<metro_viewer::CharacterBounds> character_bounds;
    483   for (size_t i = 0; i < composition_character_bounds.size(); ++i) {
    484     const gfx::Rect& rect = composition_character_bounds[i];
    485     metro_viewer::CharacterBounds bounds;
    486     bounds.left = rect.x();
    487     bounds.top = rect.y();
    488     bounds.right = rect.right();
    489     bounds.bottom = rect.bottom();
    490     character_bounds.push_back(bounds);
    491   }
    492   host_->Send(new MetroViewerHostMsg_ImeTextInputClientUpdated(
    493       input_scopes, character_bounds));
    494 }
    495 
    496 void RemoteRootWindowHostWin::OnMouseMoved(int32 x, int32 y, int32 flags) {
    497   if (ignore_mouse_moves_until_set_cursor_ack_)
    498     return;
    499 
    500   gfx::Point location(x, y);
    501   ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location, flags);
    502   delegate_->OnHostMouseEvent(&event);
    503 }
    504 
    505 void RemoteRootWindowHostWin::OnMouseButton(
    506     int32 x,
    507     int32 y,
    508     int32 extra,
    509     ui::EventType type,
    510     ui::EventFlags flags) {
    511   gfx::Point location(x, y);
    512   ui::MouseEvent mouse_event(type, location, location, flags);
    513 
    514   SetEventFlags(flags | key_event_flags());
    515   if (type == ui::ET_MOUSEWHEEL) {
    516     ui::MouseWheelEvent wheel_event(mouse_event, 0, extra);
    517     delegate_->OnHostMouseEvent(&wheel_event);
    518   } else if (type == ui::ET_MOUSE_PRESSED) {
    519     // TODO(shrikant): Ideally modify code in event.cc by adding automatic
    520     // tracking of double clicks in synthetic MouseEvent constructor code.
    521     // Non-synthetic MouseEvent constructor code does automatically track
    522     // this. Need to use some caution while modifying synthetic constructor
    523     // as many tests and other code paths depend on it and apparently
    524     // specifically depend on non implicit tracking of previous mouse event.
    525     if (last_mouse_click_event_ &&
    526         ui::MouseEvent::IsRepeatedClickEvent(mouse_event,
    527                                              *last_mouse_click_event_)) {
    528       mouse_event.SetClickCount(2);
    529     } else {
    530       mouse_event.SetClickCount(1);
    531     }
    532     last_mouse_click_event_ .reset(new ui::MouseEvent(mouse_event));
    533     delegate_->OnHostMouseEvent(&mouse_event);
    534   } else {
    535     delegate_->OnHostMouseEvent(&mouse_event);
    536   }
    537 }
    538 
    539 void RemoteRootWindowHostWin::OnKeyDown(uint32 vkey,
    540                                         uint32 repeat_count,
    541                                         uint32 scan_code,
    542                                         uint32 flags) {
    543   DispatchKeyboardMessage(ui::ET_KEY_PRESSED, vkey, repeat_count, scan_code,
    544                           flags, false);
    545 }
    546 
    547 void RemoteRootWindowHostWin::OnKeyUp(uint32 vkey,
    548                                       uint32 repeat_count,
    549                                       uint32 scan_code,
    550                                       uint32 flags) {
    551   DispatchKeyboardMessage(ui::ET_KEY_RELEASED, vkey, repeat_count, scan_code,
    552                           flags, false);
    553 }
    554 
    555 void RemoteRootWindowHostWin::OnChar(uint32 key_code,
    556                                      uint32 repeat_count,
    557                                      uint32 scan_code,
    558                                      uint32 flags) {
    559   DispatchKeyboardMessage(ui::ET_KEY_PRESSED, key_code, repeat_count,
    560                           scan_code, flags, true);
    561 }
    562 
    563 void RemoteRootWindowHostWin::OnWindowActivated() {
    564   delegate_->OnHostActivated();
    565 }
    566 
    567 void RemoteRootWindowHostWin::OnTouchDown(int32 x,
    568                                           int32 y,
    569                                           uint64 timestamp,
    570                                           uint32 pointer_id) {
    571   ui::TouchEvent event(ui::ET_TOUCH_PRESSED,
    572                        gfx::Point(x, y),
    573                        pointer_id,
    574                        base::TimeDelta::FromMicroseconds(timestamp));
    575   delegate_->OnHostTouchEvent(&event);
    576 }
    577 
    578 void RemoteRootWindowHostWin::OnTouchUp(int32 x,
    579                                         int32 y,
    580                                         uint64 timestamp,
    581                                         uint32 pointer_id) {
    582   ui::TouchEvent event(ui::ET_TOUCH_RELEASED,
    583                        gfx::Point(x, y),
    584                        pointer_id,
    585                        base::TimeDelta::FromMicroseconds(timestamp));
    586   delegate_->OnHostTouchEvent(&event);
    587 }
    588 
    589 void RemoteRootWindowHostWin::OnTouchMoved(int32 x,
    590                                            int32 y,
    591                                            uint64 timestamp,
    592                                            uint32 pointer_id) {
    593   ui::TouchEvent event(ui::ET_TOUCH_MOVED,
    594                        gfx::Point(x, y),
    595                        pointer_id,
    596                        base::TimeDelta::FromMicroseconds(timestamp));
    597   delegate_->OnHostTouchEvent(&event);
    598 }
    599 
    600 void RemoteRootWindowHostWin::OnFileSaveAsDone(bool success,
    601                                                const base::FilePath& filename,
    602                                                int filter_index) {
    603   if (success)
    604     file_saveas_completion_callback_.Run(filename, filter_index, NULL);
    605   else
    606     failure_callback_.Run(NULL);
    607   file_saveas_completion_callback_.Reset();
    608   failure_callback_.Reset();
    609 }
    610 
    611 
    612 void RemoteRootWindowHostWin::OnFileOpenDone(bool success,
    613                                              const base::FilePath& filename) {
    614   if (success)
    615     file_open_completion_callback_.Run(base::FilePath(filename), 0, NULL);
    616   else
    617     failure_callback_.Run(NULL);
    618   file_open_completion_callback_.Reset();
    619   failure_callback_.Reset();
    620 }
    621 
    622 void RemoteRootWindowHostWin::OnMultiFileOpenDone(
    623     bool success,
    624     const std::vector<base::FilePath>& files) {
    625   if (success)
    626     multi_file_open_completion_callback_.Run(files, NULL);
    627   else
    628     failure_callback_.Run(NULL);
    629   multi_file_open_completion_callback_.Reset();
    630   failure_callback_.Reset();
    631 }
    632 
    633 void RemoteRootWindowHostWin::OnSelectFolderDone(
    634     bool success,
    635     const base::FilePath& folder) {
    636   if (success)
    637     select_folder_completion_callback_.Run(base::FilePath(folder), 0, NULL);
    638   else
    639     failure_callback_.Run(NULL);
    640   select_folder_completion_callback_.Reset();
    641   failure_callback_.Reset();
    642 }
    643 
    644 void RemoteRootWindowHostWin::OnSetCursorPosAck() {
    645   DCHECK(ignore_mouse_moves_until_set_cursor_ack_);
    646   ignore_mouse_moves_until_set_cursor_ack_ = false;
    647 }
    648 
    649 ui::RemoteInputMethodPrivateWin*
    650 RemoteRootWindowHostWin::GetRemoteInputMethodPrivate() {
    651   ui::InputMethod* input_method = GetAshWindow()->GetProperty(
    652       aura::client::kRootWindowInputMethodKey);
    653   return ui::RemoteInputMethodPrivateWin::Get(input_method);
    654 }
    655 
    656 void RemoteRootWindowHostWin::OnImeCandidatePopupChanged(bool visible) {
    657   ui::RemoteInputMethodPrivateWin* remote_input_method_private =
    658       GetRemoteInputMethodPrivate();
    659   if (!remote_input_method_private)
    660     return;
    661   remote_input_method_private->OnCandidatePopupChanged(visible);
    662 }
    663 
    664 void RemoteRootWindowHostWin::OnImeCompositionChanged(
    665     const string16& text,
    666     int32 selection_start,
    667     int32 selection_end,
    668     const std::vector<metro_viewer::UnderlineInfo>& underlines) {
    669   ui::RemoteInputMethodPrivateWin* remote_input_method_private =
    670       GetRemoteInputMethodPrivate();
    671   if (!remote_input_method_private)
    672     return;
    673   ui::CompositionText composition_text;
    674   FillCompositionText(
    675       text, selection_start, selection_end, underlines, &composition_text);
    676   remote_input_method_private->OnCompositionChanged(composition_text);
    677 }
    678 
    679 void RemoteRootWindowHostWin::OnImeTextCommitted(const string16& text) {
    680   ui::RemoteInputMethodPrivateWin* remote_input_method_private =
    681       GetRemoteInputMethodPrivate();
    682   if (!remote_input_method_private)
    683     return;
    684   remote_input_method_private->OnTextCommitted(text);
    685 }
    686 
    687 void RemoteRootWindowHostWin::OnImeInputSourceChanged(uint16 language_id,
    688                                                       bool is_ime) {
    689   ui::RemoteInputMethodPrivateWin* remote_input_method_private =
    690       GetRemoteInputMethodPrivate();
    691   if (!remote_input_method_private)
    692     return;
    693   remote_input_method_private->OnInputSourceChanged(language_id, is_ime);
    694 }
    695 
    696 void RemoteRootWindowHostWin::DispatchKeyboardMessage(ui::EventType type,
    697                                                       uint32 vkey,
    698                                                       uint32 repeat_count,
    699                                                       uint32 scan_code,
    700                                                       uint32 flags,
    701                                                       bool is_character) {
    702   SetEventFlags(flags | mouse_event_flags());
    703   if (base::MessageLoop::current()->IsNested()) {
    704     int index = (flags & ui::EF_ALT_DOWN) ? 1 : 0;
    705     const int char_message[] = {WM_CHAR, WM_SYSCHAR};
    706     const int keydown_message[] = {WM_KEYDOWN, WM_SYSKEYDOWN};
    707     const int keyup_message[] = {WM_KEYUP, WM_SYSKEYUP};
    708     uint32 message = is_character
    709                          ? char_message[index]
    710                          : (type == ui::ET_KEY_PRESSED ? keydown_message[index]
    711                                                        : keyup_message[index]);
    712     ::PostThreadMessage(::GetCurrentThreadId(),
    713                         message,
    714                         vkey,
    715                         repeat_count | scan_code >> 15);
    716   } else {
    717     ui::KeyEvent event(type,
    718                        ui::KeyboardCodeForWindowsKeyCode(vkey),
    719                        flags,
    720                        is_character);
    721     delegate_->OnHostKeyEvent(&event);
    722   }
    723 }
    724 
    725 void RemoteRootWindowHostWin::SetEventFlags(uint32 flags) {
    726   if (flags == event_flags_)
    727     return;
    728   event_flags_ = flags;
    729   SetVirtualKeyStates(event_flags_);
    730 }
    731 
    732 }  // namespace aura
    733