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

Unified Diff: remoting/host/input_injector_win.cc

Issue 1865543003: Update input_injector_win.cc to support injecting wheel-x and wheel-y events together (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/input_injector_win.cc
diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc
index d1fefa9b0e4ef43dcc0b2d687346f71d061f9e1f..45d4efa393e6bb319ee601e3c8b611a595de36db 100644
--- a/remoting/host/input_injector_win.cc
+++ b/remoting/host/input_injector_win.cc
@@ -8,6 +8,7 @@
#include <windows.h>
#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/compiler_specific.h"
@@ -25,6 +26,13 @@
namespace remoting {
+using protocol::ClipboardEvent;
+using protocol::KeyEvent;
+using protocol::TextEvent;
+using protocol::MouseEvent;
+using protocol::TouchEvent;
+using std::vector;
Sergey Ulanov 2016/04/06 18:25:31 Please just refer to std::vector<> everywhere belo
Hzj_jie 2016/04/06 19:56:34 Yes, I can do it, but why do we prefer removing th
Sergey Ulanov 2016/04/06 20:42:20 We don't use using statement for STL types anywher
Hzj_jie 2016/04/06 21:41:05 Done.
+
namespace {
// Helper used to call SendInput() API.
@@ -52,11 +60,99 @@ void SendKeyboardInput(uint32_t flags, uint16_t scancode) {
PLOG(ERROR) << "Failed to inject a key event";
}
-using protocol::ClipboardEvent;
-using protocol::KeyEvent;
-using protocol::TextEvent;
-using protocol::MouseEvent;
-using protocol::TouchEvent;
+// Parse move related operations from the input MouseEvent, and insert the
+// result into output.
+void ParseMouseMoveEvent(const MouseEvent& event, vector<INPUT>* output) {
+ DCHECK(output != nullptr);
Sergey Ulanov 2016/04/06 18:25:31 This should be DCHECK(output), but I don't think t
Hzj_jie 2016/04/06 19:56:34 Similar as above, why do we prefer to use, say, 'i
Sergey Ulanov 2016/04/06 20:42:20 Mainly for consistency with all other code. In thi
Hzj_jie 2016/04/06 21:41:05 Done.
+ INPUT input{};
Sergey Ulanov 2016/04/06 18:25:31 C++11 initialization syntax is currently banned, s
Hzj_jie 2016/04/06 19:56:34 Done.
+ input.type = INPUT_MOUSE;
+
+ if (event.has_delta_x() && event.has_delta_y()) {
+ input.mi.dx = event.delta_x();
+ input.mi.dy = event.delta_y();
+ input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
+ } else if (event.has_x() && event.has_y()) {
+ int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ if (width > 1 && height > 1) {
+ int x = std::max(0, std::min(width, event.x()));
+ int y = std::max(0, std::min(height, event.y()));
+ input.mi.dx = static_cast<int>((x * 65535) / (width - 1));
+ input.mi.dy = static_cast<int>((y * 65535) / (height - 1));
+ input.mi.dwFlags =
+ MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
+ }
+ } else {
+ return;
+ }
+
+ output->push_back(std::move(input));
Sergey Ulanov 2016/04/06 18:25:31 INPUT is a just a struct. I don't think you need s
Hzj_jie 2016/04/06 19:56:34 Since it's a trivial type, a move constructor is a
Sergey Ulanov 2016/04/06 20:42:20 Interesting. How can it be optimized? push_back()
Hzj_jie 2016/04/06 21:41:05 Sorry, I did not express my opinion clear. I do no
+}
+
+// Parse click related operations from the input MouseEvent, and insert the
+// result into output.
+void ParseMouseClickEvent(const MouseEvent& event, vector<INPUT>* output) {
+ DCHECK(output != nullptr);
+
+ if (event.has_button() && event.has_button_down()) {
+ INPUT input{};
+ input.type = INPUT_MOUSE;
+
+ MouseEvent::MouseButton button = event.button();
+ bool down = event.button_down();
+
+ // If the host is configured to swap left & right buttons, inject swapped
+ // events to un-do that re-mapping.
+ if (GetSystemMetrics(SM_SWAPBUTTON)) {
+ if (button == MouseEvent::BUTTON_LEFT) {
+ button = MouseEvent::BUTTON_RIGHT;
+ } else if (button == MouseEvent::BUTTON_RIGHT) {
+ button = MouseEvent::BUTTON_LEFT;
+ }
+ }
+
+ if (button == MouseEvent::BUTTON_MIDDLE) {
+ input.mi.dwFlags = down ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
+ } else if (button == MouseEvent::BUTTON_RIGHT) {
+ input.mi.dwFlags = down ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
+ } else {
+ input.mi.dwFlags = down ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
+ }
+
+ output->push_back(std::move(input));
+ }
+}
+
+// Parse wheel related operations from the input MouseEvent, and insert the
+// result into output.
+void ParseMouseWheelEvent(const MouseEvent& event, vector<INPUT>* output) {
+ DCHECK(output != nullptr);
+
+ if (event.has_wheel_delta_x()) {
+ int delta = static_cast<int>(event.wheel_delta_x());
+ if (delta != 0) {
+ INPUT input{};
+ input.type = INPUT_MOUSE;
+ input.mi.mouseData = delta;
+ // According to MSDN, if dwFlags does not contain MOUSEEVENTF_WHEEL, the
+ // event should have mouseData = 0. Without MOUSEDEVENTF_WHEEL, mouseData
+ // > 0 will cause this INPUT to be invalid.
Sergey Ulanov 2016/04/06 18:25:31 This comment is confusing. Maybe just say that bot
Hzj_jie 2016/04/06 19:56:34 Updated. The original implementation has two issu
+ input.mi.dwFlags = MOUSEEVENTF_HWHEEL | MOUSEEVENTF_WHEEL;
+ output->push_back(std::move(input));
+ }
+ }
+
+ if (event.has_wheel_delta_y()) {
+ int delta = static_cast<int>(event.wheel_delta_y());
+ if (delta != 0) {
+ INPUT input{};
+ input.type = INPUT_MOUSE;
+ input.mi.mouseData = delta;
+ input.mi.dwFlags = MOUSEEVENTF_WHEEL;
+ output->push_back(std::move(input));
+ }
+ }
+}
// A class to generate events on Windows.
class InputInjectorWin : public InputInjector {
@@ -276,72 +372,13 @@ void InputInjectorWin::Core::HandleMouse(const MouseEvent& event) {
// Reset the system idle suspend timeout.
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
- INPUT input;
- memset(&input, 0, sizeof(input));
- input.type = INPUT_MOUSE;
-
- if (event.has_delta_x() && event.has_delta_y()) {
- input.mi.dx = event.delta_x();
- input.mi.dy = event.delta_y();
- input.mi.dwFlags |= MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
- } else if (event.has_x() && event.has_y()) {
- int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
- int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
- if (width > 1 && height > 1) {
- int x = std::max(0, std::min(width, event.x()));
- int y = std::max(0, std::min(height, event.y()));
- input.mi.dx = static_cast<int>((x * 65535) / (width - 1));
- input.mi.dy = static_cast<int>((y * 65535) / (height - 1));
- input.mi.dwFlags |=
- MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
- }
- }
-
- int wheel_delta_x = 0;
- int wheel_delta_y = 0;
- if (event.has_wheel_delta_x() && event.has_wheel_delta_y()) {
- wheel_delta_x = static_cast<int>(event.wheel_delta_x());
- wheel_delta_y = static_cast<int>(event.wheel_delta_y());
- }
-
- if (wheel_delta_x != 0 || wheel_delta_y != 0) {
- if (wheel_delta_x != 0) {
- input.mi.mouseData = wheel_delta_x;
- input.mi.dwFlags |= MOUSEEVENTF_HWHEEL;
- }
- if (wheel_delta_y != 0) {
- input.mi.mouseData = wheel_delta_y;
- input.mi.dwFlags |= MOUSEEVENTF_WHEEL;
- }
- }
-
- if (event.has_button() && event.has_button_down()) {
- MouseEvent::MouseButton button = event.button();
- bool down = event.button_down();
-
- // If the host is configured to swap left & right buttons, inject swapped
- // events to un-do that re-mapping.
- if (GetSystemMetrics(SM_SWAPBUTTON)) {
- if (button == MouseEvent::BUTTON_LEFT) {
- button = MouseEvent::BUTTON_RIGHT;
- } else if (button == MouseEvent::BUTTON_RIGHT) {
- button = MouseEvent::BUTTON_LEFT;
- }
- }
-
- if (button == MouseEvent::BUTTON_LEFT) {
- input.mi.dwFlags |= down ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
- } else if (button == MouseEvent::BUTTON_MIDDLE) {
- input.mi.dwFlags |= down ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
- } else if (button == MouseEvent::BUTTON_RIGHT) {
- input.mi.dwFlags |= down ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
- } else {
- input.mi.dwFlags |= down ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
- }
- }
+ vector<INPUT> inputs;
+ ParseMouseMoveEvent(event, &inputs);
+ ParseMouseClickEvent(event, &inputs);
+ ParseMouseWheelEvent(event, &inputs);
- if (input.mi.dwFlags) {
- if (SendInput(1, &input, sizeof(INPUT)) == 0)
+ if (!inputs.empty()) {
+ if (SendInput(inputs.size(), inputs.data(), sizeof(INPUT)) != inputs.size())
PLOG(ERROR) << "Failed to inject a mouse event";
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698