mouse_cursor_monitor_aura.cc 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright 2014 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. #include "remoting/host/chromeos/mouse_cursor_monitor_aura.h"
  5. #include <utility>
  6. #include "ash/shell.h"
  7. #include "base/bind.h"
  8. #include "base/callback.h"
  9. #include "base/location.h"
  10. #include "remoting/host/chromeos/skia_bitmap_desktop_frame.h"
  11. #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
  12. #include "ui/aura/env.h"
  13. #include "ui/aura/window.h"
  14. #include "ui/aura/window_tree_host.h"
  15. #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
  16. #include "ui/wm/core/cursor_lookup.h"
  17. namespace {
  18. // Creates an empty webrtc::MouseCursor. The caller is responsible for
  19. // destroying the returned cursor.
  20. webrtc::MouseCursor* CreateEmptyMouseCursor() {
  21. return new webrtc::MouseCursor(
  22. new webrtc::BasicDesktopFrame(webrtc::DesktopSize(0, 0)),
  23. webrtc::DesktopVector(0, 0));
  24. }
  25. } // namespace
  26. namespace remoting {
  27. MouseCursorMonitorAura::MouseCursorMonitorAura()
  28. : callback_(nullptr),
  29. mode_(SHAPE_AND_POSITION) {
  30. }
  31. void MouseCursorMonitorAura::Init(Callback* callback, Mode mode) {
  32. DCHECK(!callback_);
  33. DCHECK(callback);
  34. callback_ = callback;
  35. mode_ = mode;
  36. }
  37. void MouseCursorMonitorAura::Capture() {
  38. // Check if the cursor is different.
  39. gfx::NativeCursor cursor =
  40. ash::Shell::GetPrimaryRootWindow()->GetHost()->last_cursor();
  41. if (cursor != last_cursor_) {
  42. last_cursor_ = cursor;
  43. NotifyCursorChanged(cursor);
  44. }
  45. // Check if we need to update the location.
  46. if (mode_ == SHAPE_AND_POSITION) {
  47. gfx::Point position = aura::Env::GetInstance()->last_mouse_location();
  48. if (position != last_mouse_location_) {
  49. last_mouse_location_ = position;
  50. callback_->OnMouseCursorPosition(
  51. webrtc::DesktopVector(position.x(), position.y()));
  52. }
  53. }
  54. }
  55. void MouseCursorMonitorAura::NotifyCursorChanged(const ui::Cursor& cursor) {
  56. if (cursor.type() == ui::mojom::CursorType::kNone) {
  57. callback_->OnMouseCursor(CreateEmptyMouseCursor());
  58. return;
  59. }
  60. std::unique_ptr<SkBitmap> cursor_bitmap =
  61. std::make_unique<SkBitmap>(wm::GetCursorBitmap(cursor));
  62. gfx::Point cursor_hotspot = wm::GetCursorHotspot(cursor);
  63. if (cursor_bitmap->isNull()) {
  64. LOG(ERROR) << "Failed to load bitmap for cursor type:"
  65. << static_cast<int>(cursor.type());
  66. callback_->OnMouseCursor(CreateEmptyMouseCursor());
  67. return;
  68. }
  69. std::unique_ptr<webrtc::DesktopFrame> image(
  70. SkiaBitmapDesktopFrame::Create(std::move(cursor_bitmap)));
  71. std::unique_ptr<webrtc::MouseCursor> cursor_shape(new webrtc::MouseCursor(
  72. image.release(),
  73. webrtc::DesktopVector(cursor_hotspot.x(), cursor_hotspot.y())));
  74. callback_->OnMouseCursor(cursor_shape.release());
  75. }
  76. } // namespace remoting