diff --git a/app/src/display.c b/app/src/display.c index 560d5614..549e3c87 100644 --- a/app/src/display.c +++ b/app/src/display.c @@ -6,6 +6,7 @@ #include #include "util/log.h" +#include "util/sdl.h" static bool sc_display_init_novideo_icon(struct sc_display *display, @@ -373,7 +374,7 @@ sc_display_update_texture(struct sc_display *display, const AVFrame *frame) { enum sc_display_result sc_display_render(struct sc_display *display, const SDL_Rect *geometry, enum sc_orientation orientation) { - SDL_RenderClear(display->renderer); + sc_sdl_render_clear(display->renderer); if (display->pending.flags) { bool ok = sc_display_apply_pending(display); @@ -418,6 +419,6 @@ sc_display_render(struct sc_display *display, const SDL_Rect *geometry, } } - SDL_RenderPresent(display->renderer); + sc_sdl_render_present(display->renderer); return SC_DISPLAY_RESULT_OK; } diff --git a/app/src/input_manager.c b/app/src/input_manager.c index 183ace64..1fe49e04 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -11,6 +11,7 @@ #include "screen.h" #include "shortcut_mod.h" #include "util/log.h" +#include "util/sdl.h" void sc_input_manager_init(struct sc_input_manager *im, @@ -672,13 +673,12 @@ sc_input_manager_process_touch(struct sc_input_manager *im, return; } - int dw; - int dh; - SDL_GetWindowSizeInPixels(im->screen->window, &dw, &dh); + struct sc_size drawable_size = + sc_sdl_get_window_size_in_pixels(im->screen->window); // SDL touch event coordinates are normalized in the range [0; 1] - int32_t x = event->x * dw; - int32_t y = event->y * dh; + int32_t x = event->x * (int32_t) drawable_size.width; + int32_t y = event->y * (int32_t) drawable_size.height; struct sc_touch_event evt = { .position = { diff --git a/app/src/mouse_capture.c b/app/src/mouse_capture.c index 86aca215..fe5022eb 100644 --- a/app/src/mouse_capture.c +++ b/app/src/mouse_capture.c @@ -81,24 +81,6 @@ sc_mouse_capture_handle_event(struct sc_mouse_capture *mc, void sc_mouse_capture_set_active(struct sc_mouse_capture *mc, bool capture) { -#ifdef __APPLE__ - // Workaround for SDL bug on macOS: - // - if (capture) { - float mouse_x, mouse_y; - SDL_GetGlobalMouseState(&mouse_x, &mouse_y); - - int x, y, w, h; - SDL_GetWindowPosition(mc->window, &x, &y); - SDL_GetWindowSize(mc->window, &w, &h); - - bool outside_window = mouse_x < x || mouse_x >= x + w - || mouse_y < y || mouse_y >= y + h; - if (outside_window) { - SDL_WarpMouseInWindow(mc->window, w / 2, h / 2); - } - } -#endif bool ok = SDL_SetWindowRelativeMouseMode(mc->window, capture); if (!ok) { LOGE("Could not set relative mouse mode to %s: %s", diff --git a/app/src/screen.c b/app/src/screen.c index 749c4fbe..2a1b91f8 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -27,38 +27,12 @@ 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) { 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) @@ -169,13 +143,10 @@ static void sc_screen_update_content_rect(struct sc_screen *screen) { assert(screen->video); - int dw; - int dh; - SDL_GetWindowSizeInPixels(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; @@ -496,13 +467,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); @@ -512,13 +488,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 @@ -548,7 +524,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, @@ -556,7 +532,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 @@ -752,8 +729,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); @@ -761,11 +738,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); } @@ -779,12 +759,12 @@ 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); } @@ -914,9 +894,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_GetWindowSizeInPixels(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; diff --git a/app/src/usb/screen_otg.c b/app/src/usb/screen_otg.c index c132f796..4beec4bc 100644 --- a/app/src/usb/screen_otg.c +++ b/app/src/usb/screen_otg.c @@ -11,7 +11,7 @@ static void sc_screen_otg_render(struct sc_screen_otg *screen) { - SDL_RenderClear(screen->renderer); + sc_sdl_render_clear(screen->renderer); if (screen->texture) { bool ok = SDL_RenderTexture(screen->renderer, screen->texture, NULL, NULL); @@ -19,7 +19,7 @@ sc_screen_otg_render(struct sc_screen_otg *screen) { LOGW("Could not render texture: %s", SDL_GetError()); } } - SDL_RenderPresent(screen->renderer); + sc_sdl_render_present(screen->renderer); } bool diff --git a/app/src/util/sdl.c b/app/src/util/sdl.c index 9142456f..2f12a6c2 100644 --- a/app/src/util/sdl.c +++ b/app/src/util/sdl.c @@ -31,3 +31,77 @@ sc_sdl_create_window(const char *title, int64_t x, int64_t y, int64_t width, SDL_DestroyProperties(props); return window; } + +struct sc_size +sc_sdl_get_window_size(SDL_Window *window) { + int width; + int height; + SDL_GetWindowSize(window, &width, &height); + + struct sc_size size = { + .width = width, + .height = height, + }; + return size; +} + +struct sc_size +sc_sdl_get_window_size_in_pixels(SDL_Window *window) { + int width; + int height; + SDL_GetWindowSizeInPixels(window, &width, &height); + + struct sc_size size = { + .width = width, + .height = height, + }; + return size; +} + +void +sc_sdl_set_window_size(SDL_Window *window, struct sc_size size) { + SDL_SetWindowSize(window, size.width, size.height); +} + +struct sc_point +sc_sdl_get_window_position(SDL_Window *window) { + int x; + int y; + SDL_GetWindowPosition(window, &x, &y); + + struct sc_point point = { + .x = x, + .y = y, + }; + return point; +} + +void +sc_sdl_set_window_position(SDL_Window *window, struct sc_point point) { + SDL_SetWindowPosition(window, point.x, point.y); +} + +void +sc_sdl_show_window(SDL_Window *window) { + SDL_ShowWindow(window); +} + +void +sc_sdl_hide_window(SDL_Window *window) { + SDL_HideWindow(window); +} + +void +sc_sdl_restore_window(SDL_Window *window) { + SDL_RestoreWindow(window); +} + +bool +sc_sdl_render_clear(SDL_Renderer *renderer) { + return SDL_RenderClear(renderer); +} + +void +sc_sdl_render_present(SDL_Renderer *renderer) { + SDL_RenderPresent(renderer); +} diff --git a/app/src/util/sdl.h b/app/src/util/sdl.h index 5612600d..e341ea19 100644 --- a/app/src/util/sdl.h +++ b/app/src/util/sdl.h @@ -4,10 +4,43 @@ #include "common.h" #include +#include #include +#include "coords.h" + SDL_Window * sc_sdl_create_window(const char *title, int64_t x, int64_t y, int64_t width, int64_t height, int64_t flags); +struct sc_size +sc_sdl_get_window_size(SDL_Window *window); + +void +sc_sdl_set_window_size(SDL_Window *window, struct sc_size size); + +struct sc_size +sc_sdl_get_window_size_in_pixels(SDL_Window *window); + +struct sc_point +sc_sdl_get_window_position(SDL_Window *window); + +void +sc_sdl_set_window_position(SDL_Window *window, struct sc_point point); + +void +sc_sdl_show_window(SDL_Window *window); + +void +sc_sdl_hide_window(SDL_Window *window); + +void +sc_sdl_restore_window(SDL_Window *window); + +bool +sc_sdl_render_clear(SDL_Renderer *renderer); + +void +sc_sdl_render_present(SDL_Renderer *renderer); + #endif