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