1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_HOST_LINUX_INPUT_INJECTOR_X11_H_
#define REMOTING_HOST_LINUX_INPUT_INJECTOR_X11_H_
#include <stddef.h>
#include <stdint.h>
#include <array>
#include <memory>
#include <optional>
#include <set>
#include <utility>
#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "remoting/host/clipboard.h"
#include "remoting/host/input_injector.h"
#include "remoting/host/linux/input_injector_constants_linux.h"
#include "remoting/host/linux/x11_character_injector.h"
#include "remoting/host/linux/x11_keyboard_impl.h"
#include "remoting/host/linux/x11_util.h"
#include "remoting/proto/internal.pb.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "ui/gfx/x/xproto.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "remoting/host/chromeos/point_transformer.h"
#endif
namespace remoting {
// A class to generate events on X11.
class InputInjectorX11 : public InputInjector {
public:
explicit InputInjectorX11(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
InputInjectorX11(const InputInjectorX11&) = delete;
InputInjectorX11& operator=(const InputInjectorX11&) = delete;
~InputInjectorX11() override;
void Init();
// Clipboard stub interface.
void InjectClipboardEvent(const protocol::ClipboardEvent& event) override;
// InputStub interface.
void InjectKeyEvent(const protocol::KeyEvent& event) override;
void InjectTextEvent(const protocol::TextEvent& event) override;
void InjectMouseEvent(const protocol::MouseEvent& event) override;
void InjectTouchEvent(const protocol::TouchEvent& event) override;
// InputInjector interface.
void Start(
std::unique_ptr<protocol::ClipboardStub> client_clipboard) override;
private:
// The actual implementation resides in InputInjectorX11::Core class.
class Core : public base::RefCountedThreadSafe<Core> {
public:
explicit Core(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
Core(const Core&) = delete;
Core& operator=(const Core&) = delete;
void Init();
// Mirrors the ClipboardStub interface.
void InjectClipboardEvent(const protocol::ClipboardEvent& event);
// Mirrors the InputStub interface.
void InjectKeyEvent(const protocol::KeyEvent& event);
void InjectTextEvent(const protocol::TextEvent& event);
void InjectMouseEvent(const protocol::MouseEvent& event);
// Mirrors the InputInjector interface.
void Start(std::unique_ptr<protocol::ClipboardStub> client_clipboard);
void Stop();
private:
friend class base::RefCountedThreadSafe<Core>;
virtual ~Core();
void InitClipboard();
// Queries whether keyboard auto-repeat is globally enabled. This is used
// to decide whether to temporarily disable then restore this setting. If
// auto-repeat has already been disabled, this class should leave it
// untouched.
bool IsAutoRepeatEnabled();
// Enables or disables keyboard auto-repeat globally.
void SetAutoRepeatEnabled(bool enabled);
// Check if the given scan code is caps lock or num lock.
bool IsLockKey(x11::KeyCode keycode);
// Sets the keyboard lock states to those provided.
void SetLockStates(std::optional<bool> caps_lock,
std::optional<bool> num_lock);
void InjectScrollWheelClicks(int button, int count);
// Compensates for global button mappings and resets the XTest device
// mapping.
void InitMouseButtonMap();
int MouseButtonToX11ButtonNumber(protocol::MouseEvent::MouseButton button);
int HorizontalScrollWheelToX11ButtonNumber(int dx);
int VerticalScrollWheelToX11ButtonNumber(int dy);
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
std::set<int> pressed_keys_;
webrtc::DesktopVector latest_mouse_position_ =
webrtc::DesktopVector(-1, -1);
float wheel_ticks_x_ = 0;
float wheel_ticks_y_ = 0;
base::Time latest_tick_y_event_;
// The direction of the last scroll event that resulted in at least one
// "tick" being injected.
ScrollDirection latest_tick_y_direction_ = ScrollDirection::NONE;
// X11 graphics context. Must only be accessed on the input thread.
raw_ptr<x11::Connection> connection_;
// Number of buttons we support.
// Left, Right, Middle, VScroll Up/Down, HScroll Left/Right, back, forward.
static const int kNumPointerButtons = 9;
std::array<int, kNumPointerButtons> pointer_button_map_;
#if BUILDFLAG(IS_CHROMEOS)
PointTransformer point_transformer_;
#endif
std::unique_ptr<Clipboard> clipboard_;
std::unique_ptr<X11CharacterInjector> character_injector_;
bool saved_auto_repeat_enabled_ = false;
};
scoped_refptr<Core> core_;
};
} // namespace remoting
#endif // REMOTING_HOST_LINUX_INPUT_INJECTOR_X11_H_
|