Fix camera movement not working in games when using mouse

This commit is contained in:
loki 2019-12-23 19:39:24 +01:00
parent 29edc88294
commit 63de33e62a
4 changed files with 158 additions and 78 deletions

0
sunshine/move_by_copy.h Executable file → Normal file
View File

View 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);
}
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);
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;
}
XFlush(disp.display);
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);
}
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
View File

0
sunshine/thread_pool.h Executable file → Normal file
View File