ExtensionInstallDialogView: fix scrolling behavior on Views (Win,Linux)
[chromium-blink-merge.git] / remoting / client / plugin / pepper_cursor_setter.cc
blob90052b1169840957b2d7d5ce18470f081a5bca31
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.
5 #include "remoting/client/plugin/pepper_cursor_setter.h"
7 #include "base/logging.h"
8 #include "ppapi/cpp/image_data.h"
9 #include "ppapi/cpp/mouse_cursor.h"
10 #include "remoting/client/plugin/empty_cursor_filter.h"
11 #include "remoting/proto/control.pb.h"
13 namespace remoting {
15 PepperCursorSetter::PepperCursorSetter(const pp::InstanceHandle& instance)
16 : instance_(instance), delegate_stub_(nullptr) {
19 PepperCursorSetter::~PepperCursorSetter() {}
21 void PepperCursorSetter::SetCursorShape(
22 const protocol::CursorShapeInfo& cursor_shape) {
23 if (SetInstanceCursor(cursor_shape)) {
24 // PPAPI cursor was set successfully, so clear delegate cursor, if any.
25 if (delegate_stub_) {
26 delegate_stub_->SetCursorShape(EmptyCursorShape());
28 } else if (delegate_stub_) {
29 // Clear PPAPI cursor and fall-back to rendering cursor via delegate.
30 pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_NONE);
31 delegate_stub_->SetCursorShape(cursor_shape);
32 } else {
33 // TODO(wez): Fall-back to cropping & re-trying the cursor iff there is no
34 // delegate and the cursor is >32x32?
35 DLOG(FATAL) << "Failed to set PPAPI cursor, and no delegate provided.";
39 bool PepperCursorSetter::SetInstanceCursor(
40 const protocol::CursorShapeInfo& cursor_shape) {
41 // If the cursor is empty then tell PPAPI there is no cursor.
42 if (IsCursorShapeEmpty(cursor_shape)) {
43 pp::MouseCursor::SetCursor(instance_, PP_MOUSECURSOR_TYPE_NONE);
44 return true;
47 // pp::MouseCursor requires image to be in the native format.
48 if (pp::ImageData::GetNativeImageDataFormat() !=
49 PP_IMAGEDATAFORMAT_BGRA_PREMUL) {
50 LOG(WARNING) << "Unable to set cursor shape - native image format is not"
51 " premultiplied BGRA";
52 return false;
55 // Create a new ImageData to pass to SetCursor().
56 pp::Size size(cursor_shape.width(), cursor_shape.height());
57 pp::Point hotspot(cursor_shape.hotspot_x(), cursor_shape.hotspot_y());
58 pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, false);
59 if (image.is_null()) {
60 LOG(WARNING) << "Unable to create cursor image";
61 return false;
64 // Fill the pixel data and pass the cursor to PPAPI to set.
65 const int kBytesPerPixel = sizeof(uint32_t);
66 const uint32_t* src_row_data = reinterpret_cast<const uint32_t*>(
67 cursor_shape.data().data());
68 const int bytes_per_row = size.width() * kBytesPerPixel;
69 uint8* dst_row_data = reinterpret_cast<uint8*>(image.data());
70 for (int row = 0; row < size.height(); row++) {
71 memcpy(dst_row_data, src_row_data, bytes_per_row);
72 src_row_data += size.width();
73 dst_row_data += image.stride();
76 return pp::MouseCursor::SetCursor(
77 instance_, PP_MOUSECURSOR_TYPE_CUSTOM, image, hotspot);
80 } // namespace remoting