|
|
|
@ -12,7 +12,7 @@
|
|
|
|
|
|
|
|
|
|
#define DISPLAY_MARGINS 96
|
|
|
|
|
|
|
|
|
|
#define DOWNCAST(SINK) container_of(SINK, struct screen, frame_sink)
|
|
|
|
|
#define DOWNCAST(SINK) container_of(SINK, struct sc_screen, frame_sink)
|
|
|
|
|
|
|
|
|
|
static inline struct sc_size
|
|
|
|
|
get_rotated_size(struct sc_size size, int rotation) {
|
|
|
|
@ -29,7 +29,7 @@ get_rotated_size(struct sc_size size, int rotation) {
|
|
|
|
|
|
|
|
|
|
// get the window size in a struct sc_size
|
|
|
|
|
static struct sc_size
|
|
|
|
|
get_window_size(const struct screen *screen) {
|
|
|
|
|
get_window_size(const struct sc_screen *screen) {
|
|
|
|
|
int width;
|
|
|
|
|
int height;
|
|
|
|
|
SDL_GetWindowSize(screen->window, &width, &height);
|
|
|
|
@ -41,7 +41,7 @@ get_window_size(const struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct sc_point
|
|
|
|
|
get_window_position(const struct screen *screen) {
|
|
|
|
|
get_window_position(const struct sc_screen *screen) {
|
|
|
|
|
int x;
|
|
|
|
|
int y;
|
|
|
|
|
SDL_GetWindowPosition(screen->window, &x, &y);
|
|
|
|
@ -54,7 +54,7 @@ get_window_position(const struct screen *screen) {
|
|
|
|
|
|
|
|
|
|
// set the window size to be applied when fullscreen is disabled
|
|
|
|
|
static void
|
|
|
|
|
set_window_size(struct screen *screen, struct sc_size new_size) {
|
|
|
|
|
set_window_size(struct sc_screen *screen, struct sc_size new_size) {
|
|
|
|
|
assert(!screen->fullscreen);
|
|
|
|
|
assert(!screen->maximized);
|
|
|
|
|
SDL_SetWindowSize(screen->window, new_size.width, new_size.height);
|
|
|
|
@ -157,7 +157,7 @@ get_initial_optimal_size(struct sc_size content_size, uint16_t req_width,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
screen_capture_mouse(struct screen *screen, bool capture) {
|
|
|
|
|
sc_screen_capture_mouse(struct sc_screen *screen, bool capture) {
|
|
|
|
|
if (SDL_SetRelativeMouseMode(capture)) {
|
|
|
|
|
LOGE("Could not set relative mouse mode to %s: %s",
|
|
|
|
|
capture ? "true" : "false", SDL_GetError());
|
|
|
|
@ -168,7 +168,7 @@ screen_capture_mouse(struct screen *screen, bool capture) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
screen_update_content_rect(struct screen *screen) {
|
|
|
|
|
sc_screen_update_content_rect(struct sc_screen *screen) {
|
|
|
|
|
int dw;
|
|
|
|
|
int dh;
|
|
|
|
|
SDL_GL_GetDrawableSize(screen->window, &dw, &dh);
|
|
|
|
@ -205,7 +205,7 @@ screen_update_content_rect(struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline SDL_Texture *
|
|
|
|
|
create_texture(struct screen *screen) {
|
|
|
|
|
create_texture(struct sc_screen *screen) {
|
|
|
|
|
SDL_Renderer *renderer = screen->renderer;
|
|
|
|
|
struct sc_size size = screen->frame_size;
|
|
|
|
|
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,
|
|
|
|
@ -236,9 +236,9 @@ create_texture(struct screen *screen) {
|
|
|
|
|
// Set the update_content_rect flag if the window or content size may have
|
|
|
|
|
// changed, so that the content rectangle is recomputed
|
|
|
|
|
static void
|
|
|
|
|
screen_render(struct screen *screen, bool update_content_rect) {
|
|
|
|
|
sc_screen_render(struct sc_screen *screen, bool update_content_rect) {
|
|
|
|
|
if (update_content_rect) {
|
|
|
|
|
screen_update_content_rect(screen);
|
|
|
|
|
sc_screen_update_content_rect(screen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_RenderClear(screen->renderer);
|
|
|
|
@ -282,20 +282,20 @@ screen_render(struct screen *screen, bool update_content_rect) {
|
|
|
|
|
// <https://stackoverflow.com/a/40693139/1987178>
|
|
|
|
|
static int
|
|
|
|
|
event_watcher(void *data, SDL_Event *event) {
|
|
|
|
|
struct screen *screen = data;
|
|
|
|
|
struct sc_screen *screen = data;
|
|
|
|
|
if (event->type == SDL_WINDOWEVENT
|
|
|
|
|
&& event->window.event == SDL_WINDOWEVENT_RESIZED) {
|
|
|
|
|
// In practice, it seems to always be called from the same thread in
|
|
|
|
|
// that specific case. Anyway, it's just a workaround.
|
|
|
|
|
screen_render(screen, true);
|
|
|
|
|
sc_screen_render(screen, true);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
screen_frame_sink_open(struct sc_frame_sink *sink) {
|
|
|
|
|
struct screen *screen = DOWNCAST(sink);
|
|
|
|
|
sc_screen_frame_sink_open(struct sc_frame_sink *sink) {
|
|
|
|
|
struct sc_screen *screen = DOWNCAST(sink);
|
|
|
|
|
(void) screen;
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
screen->open = true;
|
|
|
|
@ -306,8 +306,8 @@ screen_frame_sink_open(struct sc_frame_sink *sink) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
screen_frame_sink_close(struct sc_frame_sink *sink) {
|
|
|
|
|
struct screen *screen = DOWNCAST(sink);
|
|
|
|
|
sc_screen_frame_sink_close(struct sc_frame_sink *sink) {
|
|
|
|
|
struct sc_screen *screen = DOWNCAST(sink);
|
|
|
|
|
(void) screen;
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
screen->open = false;
|
|
|
|
@ -317,8 +317,8 @@ screen_frame_sink_close(struct sc_frame_sink *sink) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) {
|
|
|
|
|
struct screen *screen = DOWNCAST(sink);
|
|
|
|
|
sc_screen_frame_sink_push(struct sc_frame_sink *sink, const AVFrame *frame) {
|
|
|
|
|
struct sc_screen *screen = DOWNCAST(sink);
|
|
|
|
|
return sc_video_buffer_push(&screen->vb, frame);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -326,7 +326,7 @@ static void
|
|
|
|
|
sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped,
|
|
|
|
|
void *userdata) {
|
|
|
|
|
(void) vb;
|
|
|
|
|
struct screen *screen = userdata;
|
|
|
|
|
struct sc_screen *screen = userdata;
|
|
|
|
|
|
|
|
|
|
// event_failed implies previous_skipped (the previous frame may not have
|
|
|
|
|
// been consumed if the event was not sent)
|
|
|
|
@ -359,7 +359,8 @@ sc_video_buffer_on_new_frame(struct sc_video_buffer *vb, bool previous_skipped,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
screen_init(struct screen *screen, const struct screen_params *params) {
|
|
|
|
|
sc_screen_init(struct sc_screen *screen,
|
|
|
|
|
const struct sc_screen_params *params) {
|
|
|
|
|
screen->resize_pending = false;
|
|
|
|
|
screen->has_frame = false;
|
|
|
|
|
screen->fullscreen = false;
|
|
|
|
@ -502,10 +503,10 @@ screen_init(struct screen *screen, const struct screen_params *params) {
|
|
|
|
|
// different HiDPI scaling are connected
|
|
|
|
|
SDL_SetWindowSize(screen->window, window_size.width, window_size.height);
|
|
|
|
|
|
|
|
|
|
screen_update_content_rect(screen);
|
|
|
|
|
sc_screen_update_content_rect(screen);
|
|
|
|
|
|
|
|
|
|
if (params->fullscreen) {
|
|
|
|
|
screen_switch_fullscreen(screen);
|
|
|
|
|
sc_screen_switch_fullscreen(screen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef CONTINUOUS_RESIZING_WORKAROUND
|
|
|
|
@ -513,9 +514,9 @@ screen_init(struct screen *screen, const struct screen_params *params) {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static const struct sc_frame_sink_ops ops = {
|
|
|
|
|
.open = screen_frame_sink_open,
|
|
|
|
|
.close = screen_frame_sink_close,
|
|
|
|
|
.push = screen_frame_sink_push,
|
|
|
|
|
.open = sc_screen_frame_sink_open,
|
|
|
|
|
.close = sc_screen_frame_sink_close,
|
|
|
|
|
.push = sc_screen_frame_sink_push,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
screen->frame_sink.ops = &ops;
|
|
|
|
@ -544,29 +545,29 @@ error_destroy_video_buffer:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
screen_show_window(struct screen *screen) {
|
|
|
|
|
sc_screen_show_window(struct sc_screen *screen) {
|
|
|
|
|
SDL_ShowWindow(screen->window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_hide_window(struct screen *screen) {
|
|
|
|
|
sc_screen_hide_window(struct sc_screen *screen) {
|
|
|
|
|
SDL_HideWindow(screen->window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_interrupt(struct screen *screen) {
|
|
|
|
|
sc_screen_interrupt(struct sc_screen *screen) {
|
|
|
|
|
sc_video_buffer_stop(&screen->vb);
|
|
|
|
|
fps_counter_interrupt(&screen->fps_counter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_join(struct screen *screen) {
|
|
|
|
|
sc_screen_join(struct sc_screen *screen) {
|
|
|
|
|
sc_video_buffer_join(&screen->vb);
|
|
|
|
|
fps_counter_join(&screen->fps_counter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_destroy(struct screen *screen) {
|
|
|
|
|
sc_screen_destroy(struct sc_screen *screen) {
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
assert(!screen->open);
|
|
|
|
|
#endif
|
|
|
|
@ -579,7 +580,7 @@ screen_destroy(struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
resize_for_content(struct screen *screen, struct sc_size old_content_size,
|
|
|
|
|
resize_for_content(struct sc_screen *screen, struct sc_size old_content_size,
|
|
|
|
|
struct sc_size new_content_size) {
|
|
|
|
|
struct sc_size window_size = get_window_size(screen);
|
|
|
|
|
struct sc_size target_size = {
|
|
|
|
@ -593,7 +594,7 @@ resize_for_content(struct screen *screen, struct sc_size old_content_size,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
set_content_size(struct screen *screen, struct sc_size new_content_size) {
|
|
|
|
|
set_content_size(struct sc_screen *screen, struct sc_size new_content_size) {
|
|
|
|
|
if (!screen->fullscreen && !screen->maximized) {
|
|
|
|
|
resize_for_content(screen, screen->content_size, new_content_size);
|
|
|
|
|
} else if (!screen->resize_pending) {
|
|
|
|
@ -607,7 +608,7 @@ set_content_size(struct screen *screen, struct sc_size new_content_size) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
apply_pending_resize(struct screen *screen) {
|
|
|
|
|
apply_pending_resize(struct sc_screen *screen) {
|
|
|
|
|
assert(!screen->fullscreen);
|
|
|
|
|
assert(!screen->maximized);
|
|
|
|
|
if (screen->resize_pending) {
|
|
|
|
@ -618,7 +619,7 @@ apply_pending_resize(struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_set_rotation(struct screen *screen, unsigned rotation) {
|
|
|
|
|
sc_screen_set_rotation(struct sc_screen *screen, unsigned rotation) {
|
|
|
|
|
assert(rotation < 4);
|
|
|
|
|
if (rotation == screen->rotation) {
|
|
|
|
|
return;
|
|
|
|
@ -632,12 +633,12 @@ screen_set_rotation(struct screen *screen, unsigned rotation) {
|
|
|
|
|
screen->rotation = rotation;
|
|
|
|
|
LOGI("Display rotation set to %u", rotation);
|
|
|
|
|
|
|
|
|
|
screen_render(screen, true);
|
|
|
|
|
sc_screen_render(screen, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// recreate the texture and resize the window if the frame size has changed
|
|
|
|
|
static bool
|
|
|
|
|
prepare_for_frame(struct screen *screen, struct sc_size new_frame_size) {
|
|
|
|
|
prepare_for_frame(struct sc_screen *screen, struct sc_size new_frame_size) {
|
|
|
|
|
if (screen->frame_size.width != new_frame_size.width
|
|
|
|
|
|| screen->frame_size.height != new_frame_size.height) {
|
|
|
|
|
// frame dimension changed, destroy texture
|
|
|
|
@ -649,7 +650,7 @@ prepare_for_frame(struct screen *screen, struct sc_size new_frame_size) {
|
|
|
|
|
get_rotated_size(new_frame_size, screen->rotation);
|
|
|
|
|
set_content_size(screen, new_content_size);
|
|
|
|
|
|
|
|
|
|
screen_update_content_rect(screen);
|
|
|
|
|
sc_screen_update_content_rect(screen);
|
|
|
|
|
|
|
|
|
|
LOGI("New texture: %" PRIu16 "x%" PRIu16,
|
|
|
|
|
screen->frame_size.width, screen->frame_size.height);
|
|
|
|
@ -665,7 +666,7 @@ prepare_for_frame(struct screen *screen, struct sc_size new_frame_size) {
|
|
|
|
|
|
|
|
|
|
// write the frame into the texture
|
|
|
|
|
static void
|
|
|
|
|
update_texture(struct screen *screen, const AVFrame *frame) {
|
|
|
|
|
update_texture(struct sc_screen *screen, const AVFrame *frame) {
|
|
|
|
|
SDL_UpdateYUVTexture(screen->texture, NULL,
|
|
|
|
|
frame->data[0], frame->linesize[0],
|
|
|
|
|
frame->data[1], frame->linesize[1],
|
|
|
|
@ -679,7 +680,7 @@ update_texture(struct screen *screen, const AVFrame *frame) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
screen_update_frame(struct screen *screen) {
|
|
|
|
|
sc_screen_update_frame(struct sc_screen *screen) {
|
|
|
|
|
av_frame_unref(screen->frame);
|
|
|
|
|
sc_video_buffer_consume(&screen->vb, screen->frame);
|
|
|
|
|
AVFrame *frame = screen->frame;
|
|
|
|
@ -692,12 +693,12 @@ screen_update_frame(struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
update_texture(screen, frame);
|
|
|
|
|
|
|
|
|
|
screen_render(screen, false);
|
|
|
|
|
sc_screen_render(screen, false);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_switch_fullscreen(struct screen *screen) {
|
|
|
|
|
sc_screen_switch_fullscreen(struct sc_screen *screen) {
|
|
|
|
|
uint32_t new_mode = screen->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
|
|
|
if (SDL_SetWindowFullscreen(screen->window, new_mode)) {
|
|
|
|
|
LOGW("Could not switch fullscreen mode: %s", SDL_GetError());
|
|
|
|
@ -710,11 +711,11 @@ screen_switch_fullscreen(struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOGD("Switched to %s mode", screen->fullscreen ? "fullscreen" : "windowed");
|
|
|
|
|
screen_render(screen, true);
|
|
|
|
|
sc_screen_render(screen, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_resize_to_fit(struct screen *screen) {
|
|
|
|
|
sc_screen_resize_to_fit(struct sc_screen *screen) {
|
|
|
|
|
if (screen->fullscreen || screen->maximized) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -738,7 +739,7 @@ screen_resize_to_fit(struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_resize_to_pixel_perfect(struct screen *screen) {
|
|
|
|
|
sc_screen_resize_to_pixel_perfect(struct sc_screen *screen) {
|
|
|
|
|
if (screen->fullscreen) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -755,20 +756,20 @@ screen_resize_to_pixel_perfect(struct screen *screen) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool
|
|
|
|
|
screen_is_mouse_capture_key(SDL_Keycode key) {
|
|
|
|
|
sc_screen_is_mouse_capture_key(SDL_Keycode key) {
|
|
|
|
|
return key == SDLK_LALT || key == SDLK_LGUI || key == SDLK_RGUI;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
screen_handle_event(struct screen *screen, SDL_Event *event) {
|
|
|
|
|
sc_screen_handle_event(struct sc_screen *screen, SDL_Event *event) {
|
|
|
|
|
switch (event->type) {
|
|
|
|
|
case EVENT_NEW_FRAME:
|
|
|
|
|
if (!screen->has_frame) {
|
|
|
|
|
screen->has_frame = true;
|
|
|
|
|
// this is the very first frame, show the window
|
|
|
|
|
screen_show_window(screen);
|
|
|
|
|
sc_screen_show_window(screen);
|
|
|
|
|
}
|
|
|
|
|
bool ok = screen_update_frame(screen);
|
|
|
|
|
bool ok = sc_screen_update_frame(screen);
|
|
|
|
|
if (!ok) {
|
|
|
|
|
LOGW("Frame update failed\n");
|
|
|
|
|
}
|
|
|
|
@ -780,10 +781,10 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
|
|
|
|
}
|
|
|
|
|
switch (event->window.event) {
|
|
|
|
|
case SDL_WINDOWEVENT_EXPOSED:
|
|
|
|
|
screen_render(screen, true);
|
|
|
|
|
sc_screen_render(screen, true);
|
|
|
|
|
break;
|
|
|
|
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
|
|
|
screen_render(screen, true);
|
|
|
|
|
sc_screen_render(screen, true);
|
|
|
|
|
break;
|
|
|
|
|
case SDL_WINDOWEVENT_MAXIMIZED:
|
|
|
|
|
screen->maximized = true;
|
|
|
|
@ -799,11 +800,11 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
|
|
|
|
}
|
|
|
|
|
screen->maximized = false;
|
|
|
|
|
apply_pending_resize(screen);
|
|
|
|
|
screen_render(screen, true);
|
|
|
|
|
sc_screen_render(screen, true);
|
|
|
|
|
break;
|
|
|
|
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
|
|
|
|
if (screen->im.mp->relative_mode) {
|
|
|
|
|
screen_capture_mouse(screen, false);
|
|
|
|
|
sc_screen_capture_mouse(screen, false);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@ -811,7 +812,7 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
|
if (screen->im.mp->relative_mode) {
|
|
|
|
|
SDL_Keycode key = event->key.keysym.sym;
|
|
|
|
|
if (screen_is_mouse_capture_key(key)) {
|
|
|
|
|
if (sc_screen_is_mouse_capture_key(key)) {
|
|
|
|
|
if (!screen->mouse_capture_key_pressed) {
|
|
|
|
|
screen->mouse_capture_key_pressed = key;
|
|
|
|
|
return true;
|
|
|
|
@ -833,7 +834,7 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
|
|
|
|
if (key == cap) {
|
|
|
|
|
// A mouse capture key has been pressed then released:
|
|
|
|
|
// toggle the capture mouse mode
|
|
|
|
|
screen_capture_mouse(screen, !screen->mouse_captured);
|
|
|
|
|
sc_screen_capture_mouse(screen, !screen->mouse_captured);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
// Do not return, the event must be forwarded to the input
|
|
|
|
@ -860,7 +861,7 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
|
|
|
|
break;
|
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
|
if (screen->im.mp->relative_mode && !screen->mouse_captured) {
|
|
|
|
|
screen_capture_mouse(screen, true);
|
|
|
|
|
sc_screen_capture_mouse(screen, true);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -869,8 +870,8 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct sc_point
|
|
|
|
|
screen_convert_drawable_to_frame_coords(struct screen *screen,
|
|
|
|
|
int32_t x, int32_t y) {
|
|
|
|
|
sc_screen_convert_drawable_to_frame_coords(struct sc_screen *screen,
|
|
|
|
|
int32_t x, int32_t y) {
|
|
|
|
|
unsigned rotation = screen->rotation;
|
|
|
|
|
assert(rotation < 4);
|
|
|
|
|
|
|
|
|
@ -906,14 +907,14 @@ screen_convert_drawable_to_frame_coords(struct screen *screen,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct sc_point
|
|
|
|
|
screen_convert_window_to_frame_coords(struct screen *screen,
|
|
|
|
|
int32_t x, int32_t y) {
|
|
|
|
|
screen_hidpi_scale_coords(screen, &x, &y);
|
|
|
|
|
return screen_convert_drawable_to_frame_coords(screen, x, y);
|
|
|
|
|
sc_screen_convert_window_to_frame_coords(struct sc_screen *screen,
|
|
|
|
|
int32_t x, int32_t y) {
|
|
|
|
|
sc_screen_hidpi_scale_coords(screen, &x, &y);
|
|
|
|
|
return sc_screen_convert_drawable_to_frame_coords(screen, x, y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
screen_hidpi_scale_coords(struct screen *screen, int32_t *x, int32_t *y) {
|
|
|
|
|
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);
|
|
|
|
|