absolute mouse coordinates regardless of the number of monitors attached on Linux
This commit is contained in:
@@ -122,6 +122,7 @@ enum class capture_e : int {
|
|||||||
|
|
||||||
class display_t {
|
class display_t {
|
||||||
public:
|
public:
|
||||||
|
display_t() noexcept : offset_x { 0 }, offset_y { 0 } {}
|
||||||
virtual capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor) = 0;
|
virtual capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor) = 0;
|
||||||
virtual std::shared_ptr<img_t> alloc_img() = 0;
|
virtual std::shared_ptr<img_t> alloc_img() = 0;
|
||||||
|
|
||||||
@@ -133,6 +134,9 @@ public:
|
|||||||
|
|
||||||
virtual ~display_t() = default;
|
virtual ~display_t() = default;
|
||||||
|
|
||||||
|
// Offsets for when streaming a specific monitor. By default, they are 0.
|
||||||
|
int offset_x, offset_y;
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -153,12 +153,7 @@ struct x11_attr_t: public display_t
|
|||||||
*/
|
*/
|
||||||
int lastWidth, lastHeight;
|
int lastWidth, lastHeight;
|
||||||
|
|
||||||
/*
|
x11_attr_t() : xdisplay { XOpenDisplay(nullptr) }, xwindow { }, xattr { } {
|
||||||
* Offsets for when streaming a specific monitor. By default, they are 0.
|
|
||||||
*/
|
|
||||||
int displayOffsetX, displayOffsetY;
|
|
||||||
|
|
||||||
x11_attr_t() : xdisplay { XOpenDisplay(nullptr) }, xwindow { }, xattr { }, displayOffsetX { 0 }, displayOffsetY { 0 } {
|
|
||||||
XInitThreads();
|
XInitThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,8 +194,8 @@ struct x11_attr_t: public display_t
|
|||||||
|
|
||||||
width = crt_info->width;
|
width = crt_info->width;
|
||||||
height = crt_info->height;
|
height = crt_info->height;
|
||||||
displayOffsetX = crt_info->x;
|
offset_x = crt_info->x;
|
||||||
displayOffsetY = crt_info->y;
|
offset_y = crt_info->y;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
width = xattr.width;
|
width = xattr.width;
|
||||||
@@ -228,7 +223,7 @@ struct x11_attr_t: public display_t
|
|||||||
BOOST_LOG(warning)<< "X dimensions changed in non-SHM mode, request reinit"sv;
|
BOOST_LOG(warning)<< "X dimensions changed in non-SHM mode, request reinit"sv;
|
||||||
return capture_e::reinit;
|
return capture_e::reinit;
|
||||||
}
|
}
|
||||||
XImage *img { XGetImage(xdisplay.get(), xwindow, displayOffsetX, displayOffsetY, width, height, AllPlanes, ZPixmap) };
|
XImage *img { XGetImage(xdisplay.get(), xwindow, offset_x, offset_y, width, height, AllPlanes, ZPixmap) };
|
||||||
|
|
||||||
auto img_out = (x11_img_t*) img_out_base;
|
auto img_out = (x11_img_t*) img_out_base;
|
||||||
img_out->width = img->width;
|
img_out->width = img->width;
|
||||||
@@ -239,7 +234,7 @@ struct x11_attr_t: public display_t
|
|||||||
img_out->img.reset(img);
|
img_out->img.reset(img);
|
||||||
|
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
blend_cursor(xdisplay.get(), *img_out_base, displayOffsetX, displayOffsetY);
|
blend_cursor(xdisplay.get(), *img_out_base, offset_x, offset_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return capture_e::ok;
|
return capture_e::ok;
|
||||||
@@ -288,19 +283,18 @@ struct shm_attr_t: public x11_attr_t {
|
|||||||
return capture_e::reinit;
|
return capture_e::reinit;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto img_cookie = xcb_shm_get_image_unchecked(xcb.get(), display->root, displayOffsetX, displayOffsetY, width, height, ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, seg, 0);
|
auto img_cookie = xcb_shm_get_image_unchecked(xcb.get(), display->root, offset_x, offset_y, width, height, ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, seg, 0);
|
||||||
|
|
||||||
xcb_img_t img_reply { xcb_shm_get_image_reply(xcb.get(), img_cookie,nullptr) };
|
xcb_img_t img_reply { xcb_shm_get_image_reply(xcb.get(), img_cookie,nullptr) };
|
||||||
if (!img_reply) {
|
if(!img_reply) {
|
||||||
BOOST_LOG(error)
|
BOOST_LOG(error) << "Could not get image reply"sv;
|
||||||
<< "Could not get image reply"sv;
|
|
||||||
return capture_e::reinit;
|
return capture_e::reinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::copy_n((std::uint8_t*) data.data, frame_size(), img->data);
|
std::copy_n((std::uint8_t*)data.data, frame_size(), img->data);
|
||||||
|
|
||||||
if (cursor) {
|
if(cursor) {
|
||||||
blend_cursor(shm_xdisplay.get(), *img, displayOffsetX, displayOffsetY);
|
blend_cursor(shm_xdisplay.get(), *img, offset_x, offset_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return capture_e::ok;
|
return capture_e::ok;
|
||||||
|
|||||||
@@ -145,11 +145,11 @@ public:
|
|||||||
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float 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();
|
auto touchscreen = ((input_raw_t*)input.get())->touch_input.get();
|
||||||
|
|
||||||
auto scaled_x = (int)std::lround(x * ((float)target_touch_port.width / (float)touch_port.width));
|
auto scaled_x = (int)std::lround((x + touch_port.offset_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));
|
auto scaled_y = (int)std::lround((y + touch_port.offset_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_X, scaled_x);
|
||||||
libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_Y, scaled_y + touch_port.offset_y);
|
libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_Y, scaled_y);
|
||||||
libevdev_uinput_write_event(touchscreen, EV_KEY, BTN_TOOL_FINGER, 1);
|
libevdev_uinput_write_event(touchscreen, EV_KEY, BTN_TOOL_FINGER, 1);
|
||||||
libevdev_uinput_write_event(touchscreen, EV_KEY, BTN_TOOL_FINGER, 0);
|
libevdev_uinput_write_event(touchscreen, EV_KEY, BTN_TOOL_FINGER, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ input_t input() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 move_mouse(input_t &input, int deltaX, int deltaY) {
|
void move_mouse(input_t &input, int deltaX, int deltaY) {
|
||||||
INPUT i {};
|
INPUT i {};
|
||||||
|
|
||||||
|
|||||||
@@ -856,7 +856,9 @@ encode_e encode_run_sync(std::vector<std::unique_ptr<sync_session_ctx_t>> &synce
|
|||||||
return encode_e::error;
|
return encode_e::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
input::touch_port_event->raise(0, 0, img->width, img->height);
|
// absolute mouse coordinates require that the dimensions of the screen are known
|
||||||
|
input::touch_port_event->raise(disp->offset_x, disp->offset_y, disp->width, disp->height);
|
||||||
|
|
||||||
std::vector<sync_session_t> synced_sessions;
|
std::vector<sync_session_t> synced_sessions;
|
||||||
for(auto &ctx : synced_session_ctxs) {
|
for(auto &ctx : synced_session_ctxs) {
|
||||||
auto synced_session = make_synced_session(disp.get(), encoder, *img, *ctx);
|
auto synced_session = make_synced_session(disp.get(), encoder, *img, *ctx);
|
||||||
@@ -1064,9 +1066,12 @@ void capture_async(
|
|||||||
if(display->dummy_img(dummy_img.get())) {
|
if(display->dummy_img(dummy_img.get())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
input::touch_port_event->raise(0, 0, dummy_img->width, dummy_img->height);
|
|
||||||
images->raise(std::move(dummy_img));
|
images->raise(std::move(dummy_img));
|
||||||
|
|
||||||
|
// absolute mouse coordinates require that the dimensions of the screen are known
|
||||||
|
input::touch_port_event->raise(display->offset_x, display->offset_y, display->width, display->height);
|
||||||
|
|
||||||
encode_run(
|
encode_run(
|
||||||
frame_nr, key_frame_nr,
|
frame_nr, key_frame_nr,
|
||||||
shutdown_event,
|
shutdown_event,
|
||||||
|
|||||||
Reference in New Issue
Block a user