diff --git a/sunshine/move_by_copy.h b/sunshine/move_by_copy.h old mode 100755 new mode 100644 diff --git a/sunshine/platform/linux_evdev.cpp b/sunshine/platform/linux_evdev.cpp index 61457f7e..1955f11d 100644 --- a/sunshine/platform/linux_evdev.cpp +++ b/sunshine/platform/linux_evdev.cpp @@ -19,8 +19,12 @@ using evdev_t = util::safe_ptr; using uinput_t = util::safe_ptr; 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; } diff --git a/sunshine/task_pool.h b/sunshine/task_pool.h old mode 100755 new mode 100644 diff --git a/sunshine/thread_pool.h b/sunshine/thread_pool.h old mode 100755 new mode 100644