Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(532)

Unified Diff: remoting/client/plugin/chromoting_instance.cc

Issue 23484015: Added support of relative mouse motion in Chromoting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: feedback Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/client/plugin/chromoting_instance.cc
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 37bceee87bf26631c5e5b5735bff033fb6cd9594..3532b9a205d7732261725a495cab44be7770e829 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -4,6 +4,7 @@
#include "remoting/client/plugin/chromoting_instance.h"
+#include <algorithm>
#include <string>
#include <vector>
@@ -23,8 +24,8 @@
#include "net/socket/ssl_server_socket.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/dev/url_util_dev.h"
+#include "ppapi/cpp/image_data.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"
@@ -55,6 +56,12 @@ namespace {
// 32-bit BGRA is 4 bytes per pixel.
const int kBytesPerPixel = 4;
+#if defined(ARCH_CPU_LITTLE_ENDIAN)
+const uint32_t kPixelAlphaMask = 0xff000000;
+#else // !defined(ARCH_CPU_LITTLE_ENDIAN)
+const uint32_t kPixelAlphaMask = 0x000000ff;
+#endif // !defined(ARCH_CPU_LITTLE_ENDIAN)
+
// Default DPI to assume for old clients that use notifyClientResolution.
const int kDefaultDPI = 96;
@@ -125,6 +132,16 @@ std::string ConnectionErrorToString(protocol::ErrorCode error) {
return std::string();
}
+// Returns true if |pixel| is not completely transparent.
+bool IsVisiblePixel(uint32_t pixel) {
+ return (pixel & kPixelAlphaMask) != 0;
+}
+
+// Returns true if there is at least one visible pixel in the given range.
+bool IsVisibleRow(const uint32_t* begin, const uint32_t* end) {
+ return std::find_if(begin, end, &IsVisiblePixel) != end;
+}
+
// This flag blocks LOGs to the UI if we're already in the middle of logging
// to the UI. This prevents a potential infinite loop if we encounter an error
// while sending the log message to the UI.
@@ -144,7 +161,7 @@ logging::LogMessageHandlerFunction g_logging_old_handler = NULL;
const char ChromotingInstance::kApiFeatures[] =
"highQualityScaling injectKeyEvent sendClipboardItem remapKey trapKey "
"notifyClientResolution pauseVideo pauseAudio asyncPin thirdPartyAuth "
- "pinlessAuth extensionMessage";
+ "pinlessAuth extensionMessage allowMouseLock";
const char ChromotingInstance::kRequestedCapabilities[] = "";
const char ChromotingInstance::kSupportedCapabilities[] = "desktopShape";
@@ -176,7 +193,7 @@ ChromotingInstance::ChromotingInstance(PP_Instance pp_instance)
input_tracker_(&mouse_input_filter_),
key_mapper_(&input_tracker_),
normalizing_input_filter_(CreateNormalizingInputFilter(&key_mapper_)),
- input_handler_(normalizing_input_filter_.get()),
+ input_handler_(this, normalizing_input_filter_.get()),
use_async_pin_dialog_(false),
weak_factory_(this) {
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL);
@@ -304,9 +321,17 @@ void ChromotingInstance::HandleMessage(const pp::Var& message) {
HandleRequestPairing(*data);
} else if (method == "extensionMessage") {
HandleExtensionMessage(*data);
+ } else if (method == "allowMouseLock") {
+ HandleAllowMouseLockMessage();
}
}
+void ChromotingInstance::DidChangeFocus(bool has_focus) {
+ DCHECK(plugin_task_runner_->BelongsToCurrentThread());
+
+ input_handler_.DidChangeFocus(has_focus);
+}
+
void ChromotingInstance::DidChangeView(const pp::View& view) {
DCHECK(plugin_task_runner_->BelongsToCurrentThread());
@@ -464,6 +489,8 @@ void ChromotingInstance::InjectClipboardEvent(
void ChromotingInstance::SetCursorShape(
const protocol::CursorShapeInfo& cursor_shape) {
+ COMPILE_ASSERT(sizeof(uint32_t) == kBytesPerPixel, rgba_pixels_are_32bit);
+
if (!cursor_shape.has_data() ||
!cursor_shape.has_width() ||
!cursor_shape.has_height() ||
@@ -500,47 +527,52 @@ void ChromotingInstance::SetCursorShape(
int hotspot_x = cursor_shape.hotspot_x();
int hotspot_y = cursor_shape.hotspot_y();
-
int bytes_per_row = width * kBytesPerPixel;
- const uint8* src_row_data = reinterpret_cast<const uint8*>(
+ int src_stride = width;
+ const uint32_t* src_row_data = reinterpret_cast<const uint32_t*>(
cursor_shape.data().data());
- int stride = bytes_per_row;
-
- // If the cursor exceeds the size permitted by PPAPI then crop it, keeping
- // the hotspot as close to the center of the new cursor shape as possible.
- if (height > kMaxCursorHeight) {
- int y = hotspot_y - (kMaxCursorHeight / 2);
- y = std::max(y, 0);
- y = std::min(y, height - kMaxCursorHeight);
-
- src_row_data += stride * y;
- height = kMaxCursorHeight;
- hotspot_y -= y;
- }
- if (width > kMaxCursorWidth) {
- int x = hotspot_x - (kMaxCursorWidth / 2);
- x = std::max(x, 0);
- x = std::min(x, height - kMaxCursorWidth);
-
- src_row_data += x * kBytesPerPixel;
- width = kMaxCursorWidth;
- bytes_per_row = width * kBytesPerPixel;
- hotspot_x -= x;
- }
+ const uint32_t* src_row_data_end = src_row_data + src_stride * height;
+
+ scoped_ptr<pp::ImageData> cursor_image;
+ pp::Point cursor_hotspot;
+
+ // Check if the cursor is visible.
+ if (IsVisibleRow(src_row_data, src_row_data_end)) {
+ // If the cursor exceeds the size permitted by PPAPI then crop it, keeping
+ // the hotspot as close to the center of the new cursor shape as possible.
+ if (height > kMaxCursorHeight) {
+ int y = hotspot_y - (kMaxCursorHeight / 2);
+ y = std::max(y, 0);
+ y = std::min(y, height - kMaxCursorHeight);
+
+ src_row_data += src_stride * y;
+ height = kMaxCursorHeight;
+ hotspot_y -= y;
+ }
+ if (width > kMaxCursorWidth) {
+ int x = hotspot_x - (kMaxCursorWidth / 2);
+ x = std::max(x, 0);
+ x = std::min(x, height - kMaxCursorWidth);
+
+ src_row_data += x;
+ width = kMaxCursorWidth;
+ bytes_per_row = width * kBytesPerPixel;
+ hotspot_x -= x;
+ }
- pp::ImageData cursor_image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
- pp::Size(width, height), false);
+ cursor_image.reset(new pp::ImageData(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(width, height), false));
+ cursor_hotspot = pp::Point(hotspot_x, hotspot_y);
- 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 += stride;
- dst_row_data += cursor_image.stride();
+ 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 += src_stride;
+ dst_row_data += cursor_image->stride();
+ }
}
- pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM,
- cursor_image,
- pp::Point(hotspot_x, hotspot_y));
+ input_handler_.SetMouseCursor(cursor_image.Pass(), cursor_hotspot);
}
void ChromotingInstance::OnFirstFrameReceived() {
@@ -860,6 +892,10 @@ void ChromotingInstance::HandleExtensionMessage(
host_connection_->host_stub()->DeliverClientMessage(message);
}
+void ChromotingInstance::HandleAllowMouseLockMessage() {
+ input_handler_.AllowMouseLock();
+}
+
ChromotingStats* ChromotingInstance::GetStats() {
if (!client_.get())
return NULL;

Powered by Google App Engine
This is Rietveld 408576698