mirror of
https://github.com/Genymobile/scrcpy
synced 2025-09-01 06:45:40 +00:00
Manually position and scale the content
Position and scale the content "manually" instead of relying on the renderer "logical size". This avoids possible rounding differences between the computed window size and the content size, causing one row or column of black pixels on the bottom or on the right. This also avoids HiDPI scale issues, by computing the scaling manually. This will also enable to draw items at their expected size on the screen (unscaled). Fixes #15 <https://github.com/Genymobile/scrcpy/issues/15>
This commit is contained in:
@@ -7,33 +7,6 @@
|
||||
#include "util/lock.h"
|
||||
#include "util/log.h"
|
||||
|
||||
// Convert window coordinates (as provided by SDL_GetMouseState() to renderer
|
||||
// coordinates (as provided in SDL mouse events)
|
||||
//
|
||||
// See my question:
|
||||
// <https://stackoverflow.com/questions/49111054/how-to-get-mouse-position-on-mouse-wheel-event>
|
||||
static void
|
||||
convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int *y) {
|
||||
SDL_Rect viewport;
|
||||
float scale_x, scale_y;
|
||||
SDL_RenderGetViewport(renderer, &viewport);
|
||||
SDL_RenderGetScale(renderer, &scale_x, &scale_y);
|
||||
*x = (int) (*x / scale_x) - viewport.x;
|
||||
*y = (int) (*y / scale_y) - viewport.y;
|
||||
}
|
||||
|
||||
static struct point
|
||||
get_mouse_point(struct screen *screen) {
|
||||
int x;
|
||||
int y;
|
||||
SDL_GetMouseState(&x, &y);
|
||||
convert_to_renderer_coordinates(screen->renderer, &x, &y);
|
||||
return (struct point) {
|
||||
.x = x,
|
||||
.y = y,
|
||||
};
|
||||
}
|
||||
|
||||
static const int ACTION_DOWN = 1;
|
||||
static const int ACTION_UP = 1 << 1;
|
||||
|
||||
@@ -487,11 +460,17 @@ convert_touch(const SDL_TouchFingerEvent *from, struct screen *screen,
|
||||
|
||||
to->inject_touch_event.pointer_id = from->fingerId;
|
||||
to->inject_touch_event.position.screen_size = screen->frame_size;
|
||||
|
||||
int ww;
|
||||
int wh;
|
||||
SDL_GL_GetDrawableSize(screen->window, &ww, &wh);
|
||||
|
||||
// SDL touch event coordinates are normalized in the range [0; 1]
|
||||
float x = from->x * screen->content_size.width;
|
||||
float y = from->y * screen->content_size.height;
|
||||
int32_t x = from->x * ww;
|
||||
int32_t y = from->y * wh;
|
||||
to->inject_touch_event.position.point =
|
||||
screen_convert_to_frame_coords(screen, x, y);
|
||||
|
||||
to->inject_touch_event.pressure = from->pressure;
|
||||
to->inject_touch_event.buttons = 0;
|
||||
return true;
|
||||
@@ -508,13 +487,6 @@ input_manager_process_touch(struct input_manager *im,
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
is_outside_device_screen(struct input_manager *im, int x, int y)
|
||||
{
|
||||
return x < 0 || x >= im->screen->content_size.width ||
|
||||
y < 0 || y >= im->screen->content_size.height;
|
||||
}
|
||||
|
||||
static bool
|
||||
convert_mouse_button(const SDL_MouseButtonEvent *from, struct screen *screen,
|
||||
struct control_msg *to) {
|
||||
@@ -552,10 +524,15 @@ input_manager_process_mouse_button(struct input_manager *im,
|
||||
action_home(im->controller, ACTION_DOWN | ACTION_UP);
|
||||
return;
|
||||
}
|
||||
|
||||
// double-click on black borders resize to fit the device screen
|
||||
if (event->button == SDL_BUTTON_LEFT && event->clicks == 2) {
|
||||
bool outside =
|
||||
is_outside_device_screen(im, event->x, event->y);
|
||||
int32_t x = event->x;
|
||||
int32_t y = event->y;
|
||||
screen_hidpi_scale_coords(im->screen, &x, &y);
|
||||
SDL_Rect *r = &im->screen->rect;
|
||||
bool outside = x < r->x || x >= r->x + r->w
|
||||
|| y < r->y || y >= r->y + r->h;
|
||||
if (outside) {
|
||||
screen_resize_to_fit(im->screen);
|
||||
return;
|
||||
@@ -579,9 +556,15 @@ input_manager_process_mouse_button(struct input_manager *im,
|
||||
static bool
|
||||
convert_mouse_wheel(const SDL_MouseWheelEvent *from, struct screen *screen,
|
||||
struct control_msg *to) {
|
||||
|
||||
// mouse_x and mouse_y are expressed in pixels relative to the window
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
SDL_GetMouseState(&mouse_x, &mouse_y);
|
||||
|
||||
struct position position = {
|
||||
.screen_size = screen->frame_size,
|
||||
.point = get_mouse_point(screen),
|
||||
.point = screen_convert_to_frame_coords(screen, mouse_x, mouse_y),
|
||||
};
|
||||
|
||||
to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT;
|
||||
|
Reference in New Issue
Block a user