Correct dimensions for touchscreen when single monitor attached

This commit is contained in:
loki 2021-05-11 23:30:56 +02:00
parent 92cd8648fa
commit 1d84c8f9ce
6 changed files with 76 additions and 22 deletions

View File

@ -13,8 +13,9 @@ extern "C" {
#include "main.h"
#include "config.h"
#include "utility.h"
#include "platform/common.h"
#include "thread_pool.h"
#include "input.h"
#include "platform/common.h"
namespace input {
@ -45,6 +46,11 @@ void free_id(std::bitset<N> &gamepad_mask, int id) {
gamepad_mask[id] = false;
}
touch_port_event_t touch_port_event;
platf::touch_port_t touch_port {
0, 0, 0, 0
};
static util::TaskPool::task_id_t task_id {};
static std::unordered_map<short, bool> key_press {};
static std::array<std::uint8_t, 5> mouse_press {};
@ -196,7 +202,20 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET pack
input->mouse_left_button_timeout = ENABLE_LEFT_BUTTON_DELAY;
}
platf::abs_mouse(platf_input, util::endian::big(packet->x), util::endian::big(packet->y));
if(touch_port_event->peek()) {
touch_port = *touch_port_event->pop();
}
float x = util::endian::big(packet->x);
float y = util::endian::big(packet->y);
float width = util::endian::big(packet->width);
float height = util::endian::big(packet->height);
auto scale_x = (float)touch_port.width / width;
auto scale_y = (float)touch_port.height / height;
platf::abs_mouse(platf_input, touch_port, x * scale_x, y * scale_y);
}
void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet) {
@ -481,6 +500,7 @@ void reset(std::shared_ptr<input_t> &input) {
}
void init() {
touch_port_event = std::make_unique<touch_port_event_t::element_type>();
platf_input = platf::input();
}

View File

@ -5,7 +5,8 @@
#ifndef SUNSHINE_INPUT_H
#define SUNSHINE_INPUT_H
#include "thread_safe.h"
#include "platform/common.h"
namespace input {
struct input_t;
@ -14,9 +15,13 @@ void print(void *input);
void reset(std::shared_ptr<input_t> &input);
void passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data);
void init();
std::shared_ptr<input_t> alloc();
using touch_port_event_t = std::unique_ptr<safe::event_t<platf::touch_port_t>>;
extern touch_port_event_t touch_port_event;
}
#endif //SUNSHINE_INPUT_H

View File

@ -58,6 +58,18 @@ using namespace std::literals;
return "unknown"sv;
}
// Dimensions for touchscreen input
struct touch_port_t {
std::uint32_t offset_x, offset_y;
std::uint32_t width, height;
constexpr touch_port_t(
std::uint32_t offset_x, std::uint32_t offset_y,
std::uint32_t width, std::uint32_t height) noexcept :
offset_x { offset_x }, offset_y { offset_y },
width { width }, height { height } {};
};
struct gamepad_state_t {
std::uint16_t buttonFlags;
std::uint8_t lt;
@ -146,7 +158,7 @@ std::shared_ptr<display_t> display(dev_type_e hwdevice_type);
input_t input();
void move_mouse(input_t &input, int deltaX, int deltaY);
void abs_mouse(input_t &input, int x, int y);
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y);
void button_mouse(input_t &input, int button, bool release);
void scroll(input_t &input, int distance);
void keyboard(input_t &input, uint16_t modcode, bool release);

View File

@ -6,6 +6,7 @@
#include <X11/Xutil.h>
#include <X11/extensions/XTest.h>
#include <cmath>
#include <cstring>
#include <filesystem>
@ -29,6 +30,11 @@ using uinput_t = util::safe_ptr<libevdev_uinput, libevdev_uinput_destroy>;
using keyboard_t = util::safe_ptr_v2<Display, int, XCloseDisplay>;
constexpr touch_port_t target_touch_port {
0, 0,
19200, 12000
};
struct input_raw_t {
public:
void clear_touchscreen() {
@ -136,11 +142,14 @@ public:
keyboard_t keyboard;
};
void abs_mouse(input_t &input, int x, int y) {
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
auto touchscreen = ((input_raw_t*)input.get())->touch_input.get();
libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_X, x);
libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_Y, y);
auto scaled_x = (int)std::lround(x * ((float)target_touch_port.width / (float)touch_port.width));
auto scaled_y = (int)std::lround(y * ((float)target_touch_port.height / (float)touch_port.height));
libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_X, scaled_x + touch_port.offset_x);
libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_Y, scaled_y + touch_port.offset_y);
libevdev_uinput_write_event(touchscreen, EV_KEY, BTN_TOOL_FINGER, 1);
libevdev_uinput_write_event(touchscreen, EV_KEY, BTN_TOOL_FINGER, 0);
@ -461,7 +470,7 @@ evdev_t touchscreen() {
input_absinfo absx {
0,
0,
1919,
target_touch_port.width,
1,
0,
28
@ -470,7 +479,7 @@ evdev_t touchscreen() {
input_absinfo absy {
0,
0,
1199,
target_touch_port.height,
1,
0,
28

View File

@ -38,10 +38,6 @@ void free_buffer(AVBufferRef *ref) {
av_buffer_unref(&ref);
}
void free_packet(AVPacket *packet) {
av_packet_free(&packet);
}
namespace nv {
enum class profile_h264_e : int {
@ -70,8 +66,6 @@ platf::pix_fmt_e map_pix_fmt(AVPixelFormat fmt);
void sw_img_to_frame(const platf::img_t &img, frame_t &frame);
void dxgi_img_to_frame(const platf::img_t &img, frame_t &frame);
util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
void dxgi_img_to_frame(const platf::img_t &img, frame_t &frame);
util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
util::Either<buffer_t, int> make_hwdevice_ctx(AVHWDeviceType type, void *hwdevice_ctx);
int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format);
@ -183,7 +177,7 @@ public:
session_t(ctx_t &&ctx, frame_t &&frame, util::wrap_ptr<platf::hwdevice_t> &&device) :
ctx { std::move(ctx) }, frame { std::move(frame) }, device { std::move(device) } {}
session_t(session_t &&other) :
session_t(session_t &&other) noexcept :
ctx { std::move(other.ctx) }, frame { std::move(other.frame) }, device { std::move(other.device) } {}
// Ensure objects are destroyed in the correct order
@ -862,6 +856,7 @@ encode_e encode_run_sync(std::vector<std::unique_ptr<sync_session_ctx_t>> &synce
return encode_e::error;
}
input::touch_port_event->raise(0, 0, img->width, img->height);
std::vector<sync_session_t> synced_sessions;
for(auto &ctx : synced_session_ctxs) {
auto synced_session = make_synced_session(disp.get(), encoder, *img, *ctx);
@ -1069,6 +1064,7 @@ void capture_async(
if(display->dummy_img(dummy_img.get())) {
return;
}
input::touch_port_event->raise(0, 0, dummy_img->width, dummy_img->height);
images->raise(std::move(dummy_img));
encode_run(

View File

@ -6,6 +6,7 @@
#define SUNSHINE_VIDEO_H
#include "thread_safe.h"
#include "input.h"
#include "platform/common.h"
extern "C" {
@ -14,16 +15,27 @@ extern "C" {
struct AVPacket;
namespace video {
void free_packet(AVPacket *packet);
struct packet_raw_t : public AVPacket {
template<class P>
explicit packet_raw_t(P *user_data) : channel_data { user_data } {
av_init_packet(this);
void init_packet() {
pts = AV_NOPTS_VALUE;
dts = AV_NOPTS_VALUE;
pos = -1;
duration = 0;
flags = 0;
stream_index = 0;
buf = nullptr;
side_data = nullptr;
side_data_elems = 0;
}
explicit packet_raw_t(std::nullptr_t null) : channel_data { nullptr } {
av_init_packet(this);
template<class P>
explicit packet_raw_t(P *user_data) : channel_data { user_data } {
init_packet();
}
explicit packet_raw_t(std::nullptr_t) : channel_data { nullptr } {
init_packet();
}
~packet_raw_t() {