Index: remoting/client/plugin/touch_input_scaler.cc |
diff --git a/remoting/client/plugin/touch_input_scaler.cc b/remoting/client/plugin/touch_input_scaler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e687fa53213c688ac35e7d24751327583229c9c7 |
--- /dev/null |
+++ b/remoting/client/plugin/touch_input_scaler.cc |
@@ -0,0 +1,59 @@ |
+// Copyright (c) 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "remoting/client/plugin/touch_input_scaler.h" |
+ |
+#include "base/logging.h" |
+#include "remoting/proto/event.pb.h" |
+ |
+namespace remoting { |
+ |
+using protocol::TouchEvent; |
+using protocol::TouchEventPoint; |
+ |
+namespace { |
+ |
+// |value| is the number to be scaled and clamped. |output_max| is the output |
+// desktop's max height or width. |input_max| is the input desktop's max height |
+// or width. |
+float ScaleAndClamp(float value, int output_max, int input_max) { |
+ value *= output_max; |
+ value /= input_max; |
Sergey Ulanov
2015/01/29 18:00:46
handle the case when input_max == 0.
Rintaro Kuroiwa
2015/01/30 17:57:01
is_empty() check as line 36 should handle that. I'
|
+ return std::max(0.0f, std::min(static_cast<float>(output_max), value)); |
+} |
+ |
+} // namespace |
+ |
+TouchInputScaler::TouchInputScaler(InputStub* input_stub) |
+ : InputFilter(input_stub) { |
+} |
+ |
+TouchInputScaler::~TouchInputScaler() { |
+} |
+ |
+void TouchInputScaler::InjectTouchEvent(const TouchEvent& event) { |
+ if (input_size_.is_empty() || output_size_.is_empty()) |
+ return; |
+ |
+ // We scale based on the maximum input & output coordinates, rather than the |
+ // input and output sizes, so that it's possible to reach the edge of the |
+ // output when up-scaling. We also take care to round up or down correctly, |
+ // which is important when down-scaling. |
+ TouchEvent out_event(event); |
+ for (int i = 0; i < out_event.touch_points().size(); ++i) { |
+ TouchEventPoint* point = out_event.mutable_touch_points(i); |
+ if (point->has_x() || point->has_y()) { |
+ DCHECK(point->has_x() && point->has_y()); |
+ point->set_x( |
+ ScaleAndClamp(point->x(), output_size_.width(), input_size_.width())); |
+ point->set_y(ScaleAndClamp(point->y(), |
+ output_size_.height(), |
+ input_size_.height())); |
+ } |
+ } |
+ |
+ InputFilter::InjectTouchEvent(out_event); |
+} |
+ |
+} // namespace remoting |