mirror of
https://github.com/Genymobile/scrcpy.git
synced 2026-04-21 01:33:36 +00:00
Migrate from SDL2 to SDL3
Refs <https://wiki.libsdl.org/SDL3/README-migration>
This commit is contained in:
parent
7fd2e486e2
commit
3dcd0baa63
38 changed files with 854 additions and 661 deletions
202
app/src/screen.c
202
app/src/screen.c
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "events.h"
|
||||
#include "icon.h"
|
||||
#include "options.h"
|
||||
#include "util/log.h"
|
||||
#include "util/sdl.h"
|
||||
|
||||
#define DISPLAY_MARGINS 96
|
||||
|
||||
|
|
@ -26,45 +27,26 @@ get_oriented_size(struct sc_size size, enum sc_orientation orientation) {
|
|||
return oriented_size;
|
||||
}
|
||||
|
||||
// get the window size in a struct sc_size
|
||||
static struct sc_size
|
||||
get_window_size(const struct sc_screen *screen) {
|
||||
int width;
|
||||
int height;
|
||||
SDL_GetWindowSize(screen->window, &width, &height);
|
||||
|
||||
struct sc_size size;
|
||||
size.width = width;
|
||||
size.height = height;
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct sc_point
|
||||
get_window_position(const struct sc_screen *screen) {
|
||||
int x;
|
||||
int y;
|
||||
SDL_GetWindowPosition(screen->window, &x, &y);
|
||||
|
||||
struct sc_point point;
|
||||
point.x = x;
|
||||
point.y = y;
|
||||
return point;
|
||||
}
|
||||
|
||||
// set the window size to be applied when fullscreen is disabled
|
||||
static void
|
||||
set_window_size(struct sc_screen *screen, struct sc_size new_size) {
|
||||
static inline void
|
||||
assert_not_fullscreen(struct sc_screen *screen) {
|
||||
(void) screen;
|
||||
assert(!screen->fullscreen);
|
||||
assert(!screen->maximized);
|
||||
assert(!screen->minimized);
|
||||
SDL_SetWindowSize(screen->window, new_size.width, new_size.height);
|
||||
}
|
||||
|
||||
// get the preferred display bounds (i.e. the screen bounds with some margins)
|
||||
static bool
|
||||
get_preferred_display_bounds(struct sc_size *bounds) {
|
||||
SDL_Rect rect;
|
||||
if (SDL_GetDisplayUsableBounds(0, &rect)) {
|
||||
SDL_DisplayID display = SDL_GetPrimaryDisplay();
|
||||
if (!display) {
|
||||
LOGW("Could not get primary display: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = SDL_GetDisplayUsableBounds(display, &rect);
|
||||
if (!ok) {
|
||||
LOGW("Could not get display usable bounds: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
|
@ -166,13 +148,10 @@ static void
|
|||
sc_screen_update_content_rect(struct sc_screen *screen) {
|
||||
assert(screen->video);
|
||||
|
||||
int dw;
|
||||
int dh;
|
||||
SDL_GL_GetDrawableSize(screen->window, &dw, &dh);
|
||||
|
||||
struct sc_size content_size = screen->content_size;
|
||||
// The drawable size is the window size * the HiDPI scale
|
||||
struct sc_size drawable_size = {dw, dh};
|
||||
struct sc_size drawable_size =
|
||||
sc_sdl_get_window_size_in_pixels(screen->window);
|
||||
|
||||
SDL_Rect *rect = &screen->rect;
|
||||
|
||||
|
|
@ -236,18 +215,18 @@ sc_screen_render_novideo(struct sc_screen *screen) {
|
|||
//
|
||||
// <https://bugzilla.libsdl.org/show_bug.cgi?id=2077>
|
||||
// <https://stackoverflow.com/a/40693139/1987178>
|
||||
static int
|
||||
static bool
|
||||
event_watcher(void *data, SDL_Event *event) {
|
||||
struct sc_screen *screen = data;
|
||||
assert(screen->video);
|
||||
|
||||
if (event->type == SDL_WINDOWEVENT
|
||||
&& event->window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
if (event->type == SDL_EVENT_WINDOW_RESIZED) {
|
||||
// In practice, it seems to always be called from the same thread in
|
||||
// that specific case. Anyway, it's just a workaround.
|
||||
sc_screen_render(screen, true);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -258,6 +237,7 @@ sc_screen_frame_sink_open(struct sc_frame_sink *sink,
|
|||
(void) ctx;
|
||||
|
||||
struct sc_screen *screen = DOWNCAST(sink);
|
||||
(void) screen;
|
||||
|
||||
if (ctx->width <= 0 || ctx->width > 0xFFFF
|
||||
|| ctx->height <= 0 || ctx->height > 0xFFFF) {
|
||||
|
|
@ -349,7 +329,7 @@ sc_screen_init(struct sc_screen *screen,
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t window_flags = SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
uint32_t window_flags = SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
if (params->always_on_top) {
|
||||
window_flags |= SDL_WINDOW_ALWAYS_ON_TOP;
|
||||
}
|
||||
|
|
@ -383,15 +363,24 @@ sc_screen_init(struct sc_screen *screen,
|
|||
}
|
||||
|
||||
// The window will be positioned and sized on first video frame
|
||||
screen->window = SDL_CreateWindow(title, x, y, width, height, window_flags);
|
||||
screen->window =
|
||||
sc_sdl_create_window(title, x, y, width, height, window_flags);
|
||||
if (!screen->window) {
|
||||
LOGE("Could not create window: %s", SDL_GetError());
|
||||
goto error_destroy_fps_counter;
|
||||
}
|
||||
|
||||
ok = SDL_StartTextInput(screen->window);
|
||||
if (!ok) {
|
||||
LOGE("Could not enable text input: %s", SDL_GetError());
|
||||
goto error_destroy_window;
|
||||
}
|
||||
|
||||
SDL_Surface *icon = scrcpy_icon_load();
|
||||
if (icon) {
|
||||
SDL_SetWindowIcon(screen->window, icon);
|
||||
if (!SDL_SetWindowIcon(screen->window, icon)) {
|
||||
LOGW("Could not set window icon: %s", SDL_GetError());
|
||||
}
|
||||
} else if (params->video) {
|
||||
// just a warning
|
||||
LOGW("Could not load icon");
|
||||
|
|
@ -438,7 +427,11 @@ sc_screen_init(struct sc_screen *screen,
|
|||
|
||||
#ifdef CONTINUOUS_RESIZING_WORKAROUND
|
||||
if (screen->video) {
|
||||
SDL_AddEventWatch(event_watcher, screen);
|
||||
ok = SDL_AddEventWatch(event_watcher, screen);
|
||||
if (!ok) {
|
||||
LOGW("Could not add event watcher for continuous resizing: %s",
|
||||
SDL_GetError());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -479,13 +472,18 @@ sc_screen_show_initial_window(struct sc_screen *screen) {
|
|||
? screen->req.x : (int) SDL_WINDOWPOS_CENTERED;
|
||||
int y = screen->req.y != SC_WINDOW_POSITION_UNDEFINED
|
||||
? screen->req.y : (int) SDL_WINDOWPOS_CENTERED;
|
||||
struct sc_point position = {
|
||||
.x = x,
|
||||
.y = y,
|
||||
};
|
||||
|
||||
struct sc_size window_size =
|
||||
get_initial_optimal_size(screen->content_size, screen->req.width,
|
||||
screen->req.height);
|
||||
|
||||
set_window_size(screen, window_size);
|
||||
SDL_SetWindowPosition(screen->window, x, y);
|
||||
assert_not_fullscreen(screen);
|
||||
sc_sdl_set_window_size(screen->window, window_size);
|
||||
sc_sdl_set_window_position(screen->window, position);
|
||||
|
||||
if (screen->req.fullscreen) {
|
||||
sc_screen_toggle_fullscreen(screen);
|
||||
|
|
@ -495,13 +493,13 @@ sc_screen_show_initial_window(struct sc_screen *screen) {
|
|||
sc_fps_counter_start(&screen->fps_counter);
|
||||
}
|
||||
|
||||
SDL_ShowWindow(screen->window);
|
||||
sc_sdl_show_window(screen->window);
|
||||
sc_screen_update_content_rect(screen);
|
||||
}
|
||||
|
||||
void
|
||||
sc_screen_hide_window(struct sc_screen *screen) {
|
||||
SDL_HideWindow(screen->window);
|
||||
sc_sdl_hide_window(screen->window);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -531,7 +529,7 @@ resize_for_content(struct sc_screen *screen, struct sc_size old_content_size,
|
|||
struct sc_size new_content_size) {
|
||||
assert(screen->video);
|
||||
|
||||
struct sc_size window_size = get_window_size(screen);
|
||||
struct sc_size window_size = sc_sdl_get_window_size(screen->window);
|
||||
struct sc_size target_size = {
|
||||
.width = (uint32_t) window_size.width * new_content_size.width
|
||||
/ old_content_size.width,
|
||||
|
|
@ -539,7 +537,8 @@ resize_for_content(struct sc_screen *screen, struct sc_size old_content_size,
|
|||
/ old_content_size.height,
|
||||
};
|
||||
target_size = get_optimal_size(target_size, new_content_size, true);
|
||||
set_window_size(screen, target_size);
|
||||
assert_not_fullscreen(screen);
|
||||
sc_sdl_set_window_size(screen->window, target_size);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -712,8 +711,8 @@ void
|
|||
sc_screen_toggle_fullscreen(struct sc_screen *screen) {
|
||||
assert(screen->video);
|
||||
|
||||
uint32_t new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
if (SDL_SetWindowFullscreen(screen->window, new_mode)) {
|
||||
bool ok = SDL_SetWindowFullscreen(screen->window, !screen->fullscreen);
|
||||
if (!ok) {
|
||||
LOGW("Could not switch fullscreen mode: %s", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
|
@ -735,8 +734,8 @@ sc_screen_resize_to_fit(struct sc_screen *screen) {
|
|||
return;
|
||||
}
|
||||
|
||||
struct sc_point point = get_window_position(screen);
|
||||
struct sc_size window_size = get_window_size(screen);
|
||||
struct sc_point point = sc_sdl_get_window_position(screen->window);
|
||||
struct sc_size window_size = sc_sdl_get_window_size(screen->window);
|
||||
|
||||
struct sc_size optimal_size =
|
||||
get_optimal_size(window_size, screen->content_size, false);
|
||||
|
|
@ -744,11 +743,14 @@ sc_screen_resize_to_fit(struct sc_screen *screen) {
|
|||
// Center the window related to the device screen
|
||||
assert(optimal_size.width <= window_size.width);
|
||||
assert(optimal_size.height <= window_size.height);
|
||||
uint32_t new_x = point.x + (window_size.width - optimal_size.width) / 2;
|
||||
uint32_t new_y = point.y + (window_size.height - optimal_size.height) / 2;
|
||||
|
||||
SDL_SetWindowSize(screen->window, optimal_size.width, optimal_size.height);
|
||||
SDL_SetWindowPosition(screen->window, new_x, new_y);
|
||||
struct sc_point new_position = {
|
||||
.x = point.x + (window_size.width - optimal_size.width) / 2,
|
||||
.y = point.y + (window_size.height - optimal_size.height) / 2,
|
||||
};
|
||||
|
||||
sc_sdl_set_window_size(screen->window, optimal_size);
|
||||
sc_sdl_set_window_position(screen->window, new_position);
|
||||
LOGD("Resized to optimal size: %ux%u", optimal_size.width,
|
||||
optimal_size.height);
|
||||
}
|
||||
|
|
@ -762,18 +764,20 @@ sc_screen_resize_to_pixel_perfect(struct sc_screen *screen) {
|
|||
}
|
||||
|
||||
if (screen->maximized) {
|
||||
SDL_RestoreWindow(screen->window);
|
||||
sc_sdl_restore_window(screen->window);
|
||||
screen->maximized = false;
|
||||
}
|
||||
|
||||
struct sc_size content_size = screen->content_size;
|
||||
SDL_SetWindowSize(screen->window, content_size.width, content_size.height);
|
||||
sc_sdl_set_window_size(screen->window, content_size);
|
||||
LOGD("Resized to pixel-perfect: %ux%u", content_size.width,
|
||||
content_size.height);
|
||||
}
|
||||
|
||||
bool
|
||||
sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
||||
// !video implies !has_video_window
|
||||
assert(screen->video || !screen->has_video_window);
|
||||
switch (event->type) {
|
||||
case SC_EVENT_NEW_FRAME: {
|
||||
bool ok = sc_screen_update_frame(screen);
|
||||
|
|
@ -783,46 +787,38 @@ sc_screen_handle_event(struct sc_screen *screen, const SDL_Event *event) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case SDL_WINDOWEVENT:
|
||||
if (!screen->video
|
||||
&& event->window.event == SDL_WINDOWEVENT_EXPOSED) {
|
||||
case SDL_EVENT_WINDOW_EXPOSED:
|
||||
if (!screen->video) {
|
||||
sc_screen_render_novideo(screen);
|
||||
} else if (screen->has_video_window) {
|
||||
sc_screen_render(screen, true);
|
||||
}
|
||||
return true;
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
if (screen->has_video_window) {
|
||||
sc_screen_render(screen, true);
|
||||
}
|
||||
return true;
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
screen->maximized = true;
|
||||
return true;
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
screen->minimized = true;
|
||||
return true;
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
if (screen->fullscreen) {
|
||||
// On Windows, in maximized+fullscreen, disabling
|
||||
// fullscreen mode unexpectedly triggers the "restored"
|
||||
// then "maximized" events, leaving the window in a
|
||||
// weird state (maximized according to the events, but
|
||||
// not maximized visually).
|
||||
return true;
|
||||
}
|
||||
|
||||
// !video implies !has_video_window
|
||||
assert(screen->video || !screen->has_video_window);
|
||||
if (!screen->has_video_window) {
|
||||
// Do nothing
|
||||
return true;
|
||||
}
|
||||
switch (event->window.event) {
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
sc_screen_render(screen, true);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
sc_screen_render(screen, true);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
screen->maximized = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
screen->minimized = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
if (screen->fullscreen) {
|
||||
// On Windows, in maximized+fullscreen, disabling
|
||||
// fullscreen mode unexpectedly triggers the "restored"
|
||||
// then "maximized" events, leaving the window in a
|
||||
// weird state (maximized according to the events, but
|
||||
// not maximized visually).
|
||||
break;
|
||||
}
|
||||
screen->maximized = false;
|
||||
screen->minimized = false;
|
||||
apply_pending_resize(screen);
|
||||
sc_screen_render(screen, true);
|
||||
break;
|
||||
screen->maximized = false;
|
||||
screen->minimized = false;
|
||||
if (screen->has_video_window) {
|
||||
apply_pending_resize(screen);
|
||||
sc_screen_render(screen, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -903,9 +899,15 @@ sc_screen_convert_window_to_frame_coords(struct sc_screen *screen,
|
|||
void
|
||||
sc_screen_hidpi_scale_coords(struct sc_screen *screen, int32_t *x, int32_t *y) {
|
||||
// take the HiDPI scaling (dw/ww and dh/wh) into account
|
||||
int ww, wh, dw, dh;
|
||||
SDL_GetWindowSize(screen->window, &ww, &wh);
|
||||
SDL_GL_GetDrawableSize(screen->window, &dw, &dh);
|
||||
|
||||
struct sc_size window_size = sc_sdl_get_window_size(screen->window);
|
||||
int64_t ww = window_size.width;
|
||||
int64_t wh = window_size.height;
|
||||
|
||||
struct sc_size drawable_size =
|
||||
sc_sdl_get_window_size_in_pixels(screen->window);
|
||||
int64_t dw = drawable_size.width;
|
||||
int64_t dh = drawable_size.height;
|
||||
|
||||
// scale for HiDPI (64 bits for intermediate multiplications)
|
||||
*x = (int64_t) *x * dw / ww;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue