-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathvirtualhid.cpp
More file actions
120 lines (102 loc) · 3.47 KB
/
Copy pathvirtualhid.cpp
File metadata and controls
120 lines (102 loc) · 3.47 KB
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
/**
* @file src/platform/linux/input/virtualhid.cpp
* @brief Definitions for libvirtualhid Unix input handling.
*/
// standard includes
#include <memory>
#include <utility>
// platform includes
#ifdef SUNSHINE_BUILD_X11
#include <X11/Xlib.h>
#endif
// local includes
#include "src/platform/virtualhid_input.h"
using namespace std::literals;
namespace platf {
platform_caps::caps_t get_capabilities() {
platform_caps::caps_t caps = 0;
const auto runtime = virtualhid::create_runtime();
if (!runtime) {
return caps;
}
if (const auto &capabilities = runtime->capabilities(); config::input.native_pen_touch && (capabilities.supports_touchscreen || capabilities.supports_pen_tablet)) {
caps |= platform_caps::pen_touch;
}
if (virtualhid::configured_gamepad_supports_touchpad()) {
caps |= platform_caps::controller_touch;
}
return caps;
}
std::optional<util::point_t> get_mouse_loc(input_t & /*input*/) {
#ifdef SUNSHINE_BUILD_X11
auto *display = XOpenDisplay(nullptr);
if (!display) {
return std::nullopt;
}
const auto root = DefaultRootWindow(display);
Window root_return {};
Window child_return {};
int root_x = 0;
int root_y = 0;
int window_x = 0;
int window_y = 0;
unsigned int mask = 0;
const auto queried = XQueryPointer(display, root, &root_return, &child_return, &root_x, &root_y, &window_x, &window_y, &mask);
XCloseDisplay(display);
if (!queried) {
return std::nullopt;
}
return util::point_t {
static_cast<double>(root_x),
static_cast<double>(root_y)
};
#else
return std::nullopt;
#endif
}
// Kept beside get_mouse_loc() rather than in misc.cpp, which is where the other two platforms
// put it, because this is the only Linux translation unit with an X11 connection already set up.
std::optional<std::array<double, 2>> pointer_location() {
#ifdef SUNSHINE_BUILD_X11
auto *display = XOpenDisplay(nullptr);
if (!display) {
return std::nullopt;
}
const auto screen = DefaultScreen(display);
const auto width = static_cast<double>(DisplayWidth(display, screen));
const auto height = static_cast<double>(DisplayHeight(display, screen));
const auto root = DefaultRootWindow(display);
Window root_return {};
Window child_return {};
int root_x = 0;
int root_y = 0;
int window_x = 0;
int window_y = 0;
unsigned int mask = 0;
const auto queried = XQueryPointer(display, root, &root_return, &child_return, &root_x, &root_y, &window_x, &window_y, &mask);
XCloseDisplay(display);
if (!queried || width <= 0 || height <= 0) {
return std::nullopt;
}
// The X screen, which spans every output. That is also what x11grab captures, so the two
// agree by default; a session capturing one output of several would need the pointer placed
// against that output instead.
return std::array<double, 2> {
root_x / width,
root_y / height
};
#else
// Wayland gives no way to ask, so the client falls back to leaving the picture alone.
return std::nullopt;
#endif
}
std::vector<supported_gamepad_t> &supported_gamepads(input_t *input) {
static std::vector<supported_gamepad_t> gamepads;
if (!input || !input->get()) {
gamepads = virtualhid::static_supported_gamepads();
return gamepads;
}
gamepads = virtualhid::supported_gamepads(virtualhid::get_input_context(*input).runtime.get());
return gamepads;
}
} // namespace platf