mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-04-16 08:42:34 +00:00
Fix camera movement not working in games when using mouse
This commit is contained in:
parent
29edc88294
commit
63de33e62a
0
sunshine/move_by_copy.h
Executable file → Normal file
0
sunshine/move_by_copy.h
Executable file → Normal file
@ -19,8 +19,12 @@ using evdev_t = util::safe_ptr<libevdev, libevdev_free>;
|
||||
using uinput_t = util::safe_ptr<libevdev_uinput, libevdev_uinput_destroy>;
|
||||
|
||||
struct input_raw_t {
|
||||
evdev_t dev;
|
||||
uinput_t uinput;
|
||||
evdev_t gamepad_dev;
|
||||
uinput_t gamepad_input;
|
||||
|
||||
evdev_t mouse_dev;
|
||||
uinput_t mouse_input;
|
||||
|
||||
display_t display;
|
||||
|
||||
gamepad_state_t gamepad_state;
|
||||
@ -42,36 +46,49 @@ struct display_attr_t {
|
||||
};
|
||||
|
||||
void move_mouse(input_t &input, int deltaX, int deltaY) {
|
||||
auto &disp = *((display_attr_t *) ((input_raw_t*)input.get())->display.get());
|
||||
auto mouse = ((input_raw_t*)input.get())->mouse_input.get();
|
||||
|
||||
XWarpPointer(disp.display, None, None, 0, 0, 0, 0, deltaX, deltaY);
|
||||
XFlush(disp.display);
|
||||
if(deltaX) {
|
||||
libevdev_uinput_write_event(mouse, EV_REL, REL_X, deltaX);
|
||||
}
|
||||
|
||||
if(deltaY) {
|
||||
libevdev_uinput_write_event(mouse, EV_REL, REL_Y, deltaY);
|
||||
}
|
||||
|
||||
libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
void button_mouse(input_t &input, int button, bool release) {
|
||||
auto &disp = *((display_attr_t *) ((input_raw_t*)input.get())->display.get());
|
||||
int btn_type;
|
||||
int scan;
|
||||
|
||||
XTestFakeButtonEvent(disp.display, button, !release, CurrentTime);
|
||||
|
||||
XFlush(disp.display);
|
||||
if(button == 1) {
|
||||
btn_type = BTN_LEFT;
|
||||
scan = 90001;
|
||||
}
|
||||
else if(button == 2) {
|
||||
btn_type = BTN_MIDDLE;
|
||||
scan = 90003;
|
||||
}
|
||||
else {
|
||||
btn_type = BTN_RIGHT;
|
||||
scan = 90002;
|
||||
}
|
||||
|
||||
void scroll(input_t &input, int distance) {
|
||||
auto &disp = *((display_attr_t *) ((input_raw_t*)input.get())->display.get());
|
||||
|
||||
int button = distance > 0 ? 4 : 5;
|
||||
|
||||
distance = std::abs(distance / 120);
|
||||
while(distance > 0) {
|
||||
--distance;
|
||||
|
||||
XTestFakeButtonEvent(disp.display, button, True, CurrentTime);
|
||||
XTestFakeButtonEvent(disp.display, button, False, CurrentTime);
|
||||
|
||||
XSync(disp.display, 0);
|
||||
auto mouse = ((input_raw_t*)input.get())->mouse_input.get();
|
||||
libevdev_uinput_write_event(mouse, EV_MSC, MSC_SCAN, scan);
|
||||
libevdev_uinput_write_event(mouse, EV_KEY, btn_type, release ? 0 : 1);
|
||||
libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
XFlush(disp.display);
|
||||
void scroll(input_t &input, int high_res_distance) {
|
||||
int distance = high_res_distance / 120;
|
||||
|
||||
auto mouse = ((input_raw_t*)input.get())->mouse_input.get();
|
||||
libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL, distance);
|
||||
libevdev_uinput_write_event(mouse, EV_REL, REL_WHEEL_HI_RES, high_res_distance);
|
||||
libevdev_uinput_write_event(mouse, EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
|
||||
uint16_t keysym(uint16_t modcode) {
|
||||
@ -205,92 +222,140 @@ namespace gp {
|
||||
// up pressed == -1, down pressed == 1, else 0
|
||||
void dpad_y(input_t &input, int button_state) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_HAT0Y, button_state);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_HAT0Y, button_state);
|
||||
}
|
||||
// left pressed == -1, right pressed == 1, else 0
|
||||
void dpad_x(input_t &input, int button_state) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_HAT0X, button_state);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_HAT0X, button_state);
|
||||
}
|
||||
void start(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_START, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_START, button_down);
|
||||
}
|
||||
void back(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_SELECT, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_SELECT, button_down);
|
||||
}
|
||||
void left_stick(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_THUMBL, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_THUMBL, button_down);
|
||||
}
|
||||
void right_stick(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_THUMBR, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_THUMBR, button_down);
|
||||
}
|
||||
void left_button(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_TL, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_TL, button_down);
|
||||
}
|
||||
void right_button(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_TR, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_TR, button_down);
|
||||
}
|
||||
void home(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_MODE, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_MODE, button_down);
|
||||
}
|
||||
void a(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_SOUTH, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_SOUTH, button_down);
|
||||
}
|
||||
void b(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_EAST, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_EAST, button_down);
|
||||
}
|
||||
void x(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_NORTH, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_NORTH, button_down);
|
||||
}
|
||||
void y(input_t &input, int button_down) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_KEY, BTN_WEST, button_down);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_KEY, BTN_WEST, button_down);
|
||||
}
|
||||
void left_trigger(input_t &input, std::uint8_t abs_z) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_Z, abs_z);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_Z, abs_z);
|
||||
}
|
||||
void right_trigger(input_t &input, std::uint8_t abs_z) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_RZ, abs_z);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_RZ, abs_z);
|
||||
}
|
||||
void left_stick_x(input_t &input, std::int16_t x) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_X, x);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_X, x);
|
||||
}
|
||||
void left_stick_y(input_t &input, std::int16_t y) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_Y, -y);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_Y, -y);
|
||||
}
|
||||
void right_stick_x(input_t &input, std::int16_t x) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_RX, x);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_RX, x);
|
||||
}
|
||||
void right_stick_y(input_t &input, std::int16_t y) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_ABS, ABS_RY, -y);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_ABS, ABS_RY, -y);
|
||||
}
|
||||
void sync(input_t &input) {
|
||||
auto &gp = *(input_raw_t*)input.get();
|
||||
libevdev_uinput_write_event(gp.uinput.get(), EV_SYN, SYN_REPORT, 0);
|
||||
libevdev_uinput_write_event(gp.gamepad_input.get(), EV_SYN, SYN_REPORT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
input_t input() {
|
||||
input_t result { new input_raw_t() };
|
||||
auto &gp = *(input_raw_t*)result.get();
|
||||
int mouse(input_raw_t &gp) {
|
||||
gp.mouse_dev.reset(libevdev_new());
|
||||
|
||||
gp.dev.reset(libevdev_new());
|
||||
libevdev_set_uniq(gp.mouse_dev.get(), "Sunshine Gamepad");
|
||||
libevdev_set_id_product(gp.mouse_dev.get(), 0x4038);
|
||||
libevdev_set_id_vendor(gp.mouse_dev.get(), 0x46D);
|
||||
libevdev_set_id_bustype(gp.mouse_dev.get(), 0x3);
|
||||
libevdev_set_id_version(gp.mouse_dev.get(), 0x111);
|
||||
libevdev_set_name(gp.mouse_dev.get(), "Logitech Wireless Mouse PID:4038");
|
||||
|
||||
libevdev_enable_event_type(gp.mouse_dev.get(), EV_KEY);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_LEFT, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_RIGHT, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_MIDDLE, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_SIDE, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_EXTRA, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_FORWARD, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_BACK, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, BTN_TASK, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 280, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 281, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 282, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 283, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 284, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 285, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 286, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_KEY, 287, nullptr);
|
||||
|
||||
libevdev_enable_event_type(gp.mouse_dev.get(), EV_REL);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_REL, REL_X, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_REL, REL_Y, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_REL, REL_WHEEL, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_REL, REL_WHEEL_HI_RES, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_REL, REL_HWHEEL, nullptr);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_REL, REL_HWHEEL_HI_RES, nullptr);
|
||||
|
||||
libevdev_enable_event_type(gp.mouse_dev.get(), EV_MSC);
|
||||
libevdev_enable_event_code(gp.mouse_dev.get(), EV_MSC, MSC_SCAN, nullptr);
|
||||
|
||||
libevdev_uinput *buf;
|
||||
int err = libevdev_uinput_create_from_device(gp.mouse_dev.get(), LIBEVDEV_UINPUT_OPEN_MANAGED, &buf);
|
||||
|
||||
gp.mouse_input.reset(buf);
|
||||
if(err) {
|
||||
std::cout << "Could not create Sunshine Mouse: "sv << strerror(-err) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gamepad(input_raw_t &gp) {
|
||||
gp.gamepad_dev.reset(libevdev_new());
|
||||
|
||||
input_absinfo stick {
|
||||
0,
|
||||
@ -316,42 +381,57 @@ input_t input() {
|
||||
0
|
||||
};
|
||||
|
||||
libevdev_set_uniq(gp.dev.get(), "Sunshine Gamepad");
|
||||
libevdev_set_id_product(gp.dev.get(), 0x28E);
|
||||
libevdev_set_id_vendor(gp.dev.get(), 0x45E);
|
||||
libevdev_set_id_bustype(gp.dev.get(), 0x3);
|
||||
libevdev_set_id_version(gp.dev.get(), 0x110);
|
||||
libevdev_set_name(gp.dev.get(), "Microsoft X-Box 360 pad");
|
||||
libevdev_set_uniq(gp.gamepad_dev.get(), "Sunshine Gamepad");
|
||||
libevdev_set_id_product(gp.gamepad_dev.get(), 0x28E);
|
||||
libevdev_set_id_vendor(gp.gamepad_dev.get(), 0x45E);
|
||||
libevdev_set_id_bustype(gp.gamepad_dev.get(), 0x3);
|
||||
libevdev_set_id_version(gp.gamepad_dev.get(), 0x110);
|
||||
libevdev_set_name(gp.gamepad_dev.get(), "Microsoft X-Box 360 pad");
|
||||
|
||||
libevdev_enable_event_type(gp.dev.get(), EV_KEY);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_WEST, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_EAST, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_NORTH, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_SOUTH, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_THUMBL, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_THUMBR, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_TR, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_TL, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_SELECT, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_MODE, nullptr);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_KEY, BTN_START, nullptr);
|
||||
libevdev_enable_event_type(gp.gamepad_dev.get(), EV_KEY);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_WEST, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_EAST, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_NORTH, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_SOUTH, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_THUMBL, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_THUMBR, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_TR, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_TL, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_SELECT, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_MODE, nullptr);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_KEY, BTN_START, nullptr);
|
||||
|
||||
libevdev_enable_event_type(gp.dev.get(), EV_ABS);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_HAT0Y, &dpad);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_HAT0X, &dpad);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_Z, &trigger);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_RZ, &trigger);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_X, &stick);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_RX, &stick);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_Y, &stick);
|
||||
libevdev_enable_event_code(gp.dev.get(), EV_ABS, ABS_RY, &stick);
|
||||
libevdev_enable_event_type(gp.gamepad_dev.get(), EV_ABS);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_HAT0Y, &dpad);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_HAT0X, &dpad);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_Z, &trigger);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_RZ, &trigger);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_X, &stick);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_RX, &stick);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_Y, &stick);
|
||||
libevdev_enable_event_code(gp.gamepad_dev.get(), EV_ABS, ABS_RY, &stick);
|
||||
|
||||
libevdev_uinput *buf;
|
||||
int err = libevdev_uinput_create_from_device(gp.dev.get(), LIBEVDEV_UINPUT_OPEN_MANAGED, &buf);
|
||||
int err = libevdev_uinput_create_from_device(gp.gamepad_dev.get(), LIBEVDEV_UINPUT_OPEN_MANAGED, &buf);
|
||||
|
||||
gp.uinput.reset(buf);
|
||||
gp.gamepad_input.reset(buf);
|
||||
if(err) {
|
||||
std::cout << "Could not create Sunshine Gamepad: "sv << strerror(-err) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
input_t input() {
|
||||
input_t result { new input_raw_t() };
|
||||
auto &gp = *(input_raw_t*)result.get();
|
||||
|
||||
if(gamepad(gp)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(mouse(gp)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
0
sunshine/task_pool.h
Executable file → Normal file
0
sunshine/task_pool.h
Executable file → Normal file
0
sunshine/thread_pool.h
Executable file → Normal file
0
sunshine/thread_pool.h
Executable file → Normal file
Loading…
x
Reference in New Issue
Block a user