Skip to content

Commit

Permalink
[Chromoting] Initial plumbing for cursor shape.
Browse files Browse the repository at this point in the history
This cl contains:
* protocol for sending cursor shape on control channel from host to client
* cross-platform (Pepper) client code for rendering host cursor
* Linux host support for reading current cursor shape

Separate CLs will follow with Mac and Windows host support.

BUG=116229
TEST=none


Review URL: https://chromiumcodereview.appspot.com/10382184

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140205 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
garykac@chromium.org committed Jun 2, 2012
1 parent 051e71e commit d65e15b
Show file tree
Hide file tree
Showing 29 changed files with 332 additions and 33 deletions.
5 changes: 5 additions & 0 deletions remoting/client/chromoting_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ void ChromotingClient::InjectClipboardEvent(
view_->GetClipboardStub()->InjectClipboardEvent(event);
}

void ChromotingClient::SetCursorShape(
const protocol::CursorShapeInfo& cursor_shape) {
view_->GetCursorShapeStub()->SetCursorShape(cursor_shape);
}

void ChromotingClient::ProcessVideoPacket(scoped_ptr<VideoPacket> packet,
const base::Closure& done) {
DCHECK(message_loop()->BelongsToCurrentThread());
Expand Down
6 changes: 5 additions & 1 deletion remoting/client/chromoting_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,14 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback,
// Return the stats recorded by this client.
ChromotingStats* GetStats();

// ClipboardStub implementation.
// ClipboardStub implementation for receiving clipboard data from host.
virtual void InjectClipboardEvent(const protocol::ClipboardEvent& event)
OVERRIDE;

// CursorShapeStub implementation for receiving cursor shape updates.
virtual void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape)
OVERRIDE;

// ConnectionToHost::HostEventCallback implementation.
virtual void OnConnectionState(
protocol::ConnectionToHost::State state,
Expand Down
4 changes: 4 additions & 0 deletions remoting/client/chromoting_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace remoting {

namespace protocol {
class ClipboardStub;
class CursorShapeStub;
} // namespace protocol

// ChromotingView defines the behavior of an object that draws a view of the
Expand All @@ -33,6 +34,9 @@ class ChromotingView {

// Get the view's ClipboardStub implementation.
virtual protocol::ClipboardStub* GetClipboardStub() = 0;

// Get the view's CursorShapeStub implementation.
virtual protocol::CursorShapeStub* GetCursorShapeStub() = 0;
};

} // namespace remoting
Expand Down
50 changes: 50 additions & 0 deletions remoting/client/plugin/chromoting_instance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "media/base/media.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/mouse_cursor.h"
#include "ppapi/cpp/rect.h"
#include "remoting/base/constants.h"
#include "remoting/base/util.h"
Expand All @@ -49,6 +50,9 @@ namespace remoting {

namespace {

// 32-bit BGRA is 4 bytes per pixel.
const int kBytesPerPixel = 4;

const int kPerfStatsIntervalMs = 1000;

std::string ConnectionStateToString(ChromotingInstance::ConnectionState state) {
Expand Down Expand Up @@ -554,6 +558,52 @@ void ChromotingInstance::InjectClipboardEvent(
PostChromotingMessage("injectClipboardItem", data.Pass());
}

void ChromotingInstance::SetCursorShape(
const protocol::CursorShapeInfo& cursor_shape) {
if (!cursor_shape.has_data() ||
!cursor_shape.has_width() ||
!cursor_shape.has_height() ||
!cursor_shape.has_hotspot_x() ||
!cursor_shape.has_hotspot_y()) {
return;
}

if (pp::ImageData::GetNativeImageDataFormat() !=
PP_IMAGEDATAFORMAT_BGRA_PREMUL) {
VLOG(2) << "Unable to set cursor shape - non-native image format";
return;
}

int width = cursor_shape.width();
int height = cursor_shape.height();

if (width > 32 || height > 32) {
VLOG(2) << "Cursor too large for SetCursor: "
<< width << "x" << height << " > 32x32";
return;
}

int hotspot_x = cursor_shape.hotspot_x();
int hotspot_y = cursor_shape.hotspot_y();

pp::ImageData cursor_image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(width, height), false);

int bytes_per_row = width * kBytesPerPixel;
const uint8* src_row_data = reinterpret_cast<const uint8*>(
cursor_shape.data().data());
uint8* dst_row_data = reinterpret_cast<uint8*>(cursor_image.data());
for (int row = 0; row < height; row++) {
memcpy(dst_row_data, src_row_data, bytes_per_row);
src_row_data += bytes_per_row;
dst_row_data += cursor_image.stride();
}

pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM,
cursor_image,
pp::Point(hotspot_x, hotspot_y));
}

// static
void ChromotingInstance::RegisterLogMessageHandler() {
base::AutoLock lock(g_logging_lock.Get());
Expand Down
6 changes: 6 additions & 0 deletions remoting/client/plugin/chromoting_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "remoting/client/plugin/pepper_plugin_thread_delegate.h"
#include "remoting/proto/event.pb.h"
#include "remoting/protocol/clipboard_stub.h"
#include "remoting/protocol/cursor_shape_stub.h"
#include "remoting/protocol/connection_to_host.h"

namespace base {
Expand Down Expand Up @@ -64,6 +65,7 @@ struct ClientConfig;

class ChromotingInstance :
public protocol::ClipboardStub,
public protocol::CursorShapeStub,
public pp::Instance,
public base::SupportsWeakPtr<ChromotingInstance> {
public:
Expand Down Expand Up @@ -125,6 +127,10 @@ class ChromotingInstance :
virtual void InjectClipboardEvent(const protocol::ClipboardEvent& event)
OVERRIDE;

// CursorShapeStub implementation.
virtual void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape)
OVERRIDE;

// Called by PepperView.
void SetDesktopSize(int width, int height);
void SetConnectionState(ConnectionState state, ConnectionError error);
Expand Down
4 changes: 4 additions & 0 deletions remoting/client/plugin/pepper_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ protocol::ClipboardStub* PepperView::GetClipboardStub() {
return instance_;
}

protocol::CursorShapeStub* PepperView::GetCursorShapeStub() {
return instance_;
}

void PepperView::SetView(const SkISize& view_size, const SkIRect& clip_area) {
bool view_changed = false;

Expand Down
1 change: 1 addition & 0 deletions remoting/client/plugin/pepper_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class PepperView : public ChromotingView,
protocol::ConnectionToHost::State state,
protocol::ErrorCode error) OVERRIDE;
virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE;
virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE;

// FrameConsumer implementation.
virtual void ApplyBuffer(const SkISize& view_size,
Expand Down
15 changes: 13 additions & 2 deletions remoting/host/capturer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@

#include "base/basictypes.h"
#include "base/callback.h"
#include "remoting/base/capture_data.h"
#include "media/base/video_frame.h"
#include "third_party/skia/include/core/SkRegion.h"

namespace remoting {

namespace protocol {
class CursorShapeInfo;
}

class CaptureData;

// A class to perform the task of capturing the image of a window.
// The capture action is asynchronous to allow maximum throughput.
//
Expand Down Expand Up @@ -49,6 +55,10 @@ class Capturer {
typedef base::Callback<void(scoped_refptr<CaptureData>)>
CaptureCompletedCallback;

// CursorShapeChangedCallback is called when the cursor shape has changed.
typedef base::Callback<void(scoped_ptr<protocol::CursorShapeInfo>)>
CursorShapeChangedCallback;

virtual ~Capturer() {};

// Create platform-specific capturer.
Expand All @@ -69,7 +79,8 @@ class Capturer {
#endif // defined(OS_LINUX)

// Called at the beginning of a capturing session.
virtual void Start() = 0;
virtual void Start(
const CursorShapeChangedCallback& callback) = 0;

// Called at the end of a capturing session.
virtual void Stop() = 0;
Expand Down
5 changes: 4 additions & 1 deletion remoting/host/capturer_fake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "remoting/host/capturer_fake.h"

#include "remoting/base/capture_data.h"

namespace remoting {

// CapturerFake generates a white picture of size kWidth x kHeight with a
Expand Down Expand Up @@ -36,7 +38,8 @@ CapturerFake::CapturerFake()
CapturerFake::~CapturerFake() {
}

void CapturerFake::Start() {
void CapturerFake::Start(
const CursorShapeChangedCallback& callback) {
}

void CapturerFake::Stop() {
Expand Down
3 changes: 2 additions & 1 deletion remoting/host/capturer_fake.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class CapturerFake : public Capturer {
virtual ~CapturerFake();

// Capturer interface.
virtual void Start() OVERRIDE;
virtual void Start(
const CursorShapeChangedCallback& callback) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void ScreenConfigurationChanged() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
Expand Down
Loading

0 comments on commit d65e15b

Please sign in to comment.