diff options
Diffstat (limited to 'src/screen')
| -rw-r--r-- | src/screen/meson.build | 12 | ||||
| -rw-r--r-- | src/screen/screen.c | 126 | ||||
| -rw-r--r-- | src/screen/screen.h | 7 | ||||
| -rw-r--r-- | src/screen/view.c | 55 | ||||
| -rw-r--r-- | src/screen/view.h | 4 |
5 files changed, 119 insertions, 85 deletions
diff --git a/src/screen/meson.build b/src/screen/meson.build index cd78988..d0bbd50 100644 --- a/src/screen/meson.build +++ b/src/screen/meson.build @@ -1,4 +1,10 @@ screen_src = ['screen.c', 'view.c'] -sekihi = subproject('sekihi').get_variable('sekihi') -screen = declare_dependency(sources: screen_src, - dependencies: [sekihi]) +sekihi = subproject('sekihi', + default_options: [ + 'api=opengl', + 'window=wayland', + 'poll=inline', + 'event-buffer=false', + 'pause=true' + ]).get_variable('sekihi') +screen = declare_dependency(sources: screen_src, dependencies: [sekihi]) diff --git a/src/screen/screen.c b/src/screen/screen.c index 82c7b12..dd4bdc6 100644 --- a/src/screen/screen.c +++ b/src/screen/screen.c @@ -3,18 +3,6 @@ #include "screen.h" -#define ZOOM_MAX 100.0 -#define ZOOM_MIN 0.02 - -#define PAN_BOUNDS 35.0 - -#define X_IN_BOUNDS(scr, view, x) \ - ((x + PAN_BOUNDS <= scr->width) && (PAN_BOUNDS - x <= view->width * view->zoom)) -#define Y_IN_BOUNDS(scr, view, y) \ - ((y + PAN_BOUNDS <= scr->height) && (PAN_BOUNDS - y <= view->height * view->zoom)) - -#define CAMU_DEFAULT_VIEW CAMU_VIEW_AUTOFIT - static struct camu_view *get_view_from_mouse_pos(struct camu_screen *scr) { struct camu_view *view = NULL; @@ -51,31 +39,30 @@ static void resize_callback(void *userdata, s32 width, s32 height) } } -static void pointer_pos_callback(void *userdata, f64 x, f64 y) +static bool pointer_pos_callback(void *userdata, f64 x, f64 y) { struct camu_screen *scr = (struct camu_screen *)userdata; struct camu_view *view = get_view_from_mouse_pos(scr); + bool queue_refresh = false; if (view) { if (scr->flags & CAMU_SCREEN_DRAGGING) { if (scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE) { - f64 nx = view->x_offset + x - scr->last_mouse_x; - if (X_IN_BOUNDS(scr, view, nx)) { - view->x_offset = nx; + f64 dx = x - scr->last_mouse_x; + f64 dy = y - scr->last_mouse_y; + if (camu_view_pan_simple(view, scr->width, scr->height, dx, dy)) { + view->mode = CAMU_VIEW_DETACHED; + queue_refresh = true; } - f64 ny = view->y_offset + y - scr->last_mouse_y; - if (Y_IN_BOUNDS(scr, view, ny)) { - view->y_offset = ny; - } - view->mode = CAMU_VIEW_DETACHED; } scr->last_click_ts = 0; } } scr->last_mouse_x = x; scr->last_mouse_y = y; + return queue_refresh; } -static void mouse_button_callback(void *userdata, u8 state, u8 button) +static bool mouse_button_callback(void *userdata, u8 state, u8 button) { struct camu_screen *scr = (struct camu_screen *)userdata; switch (button) { @@ -106,55 +93,30 @@ static void mouse_button_callback(void *userdata, u8 state, u8 button) default: break; } + return false; } -static void zoom_on_point(struct camu_screen *scr, struct camu_view *view, f64 x, f64 y, f64 v) -{ - x -= view->x_offset; - y -= view->y_offset; - x /= view->zoom; - y /= view->zoom; - - f64 prev_width = scr->width * view->zoom; - f64 prev_height = scr->height * view->zoom; - - f64 x_ratio = x / (f64)scr->width; - f64 y_ratio = y / (f64)scr->height; - - f64 zoom = view->zoom + (v * view->zoom); - if (zoom > ZOOM_MAX || zoom < ZOOM_MIN) return; - - f64 nx = view->x_offset - x_ratio * ((scr->width * zoom) - prev_width); - f64 ny = view->y_offset - y_ratio * ((scr->height * zoom) - prev_height); - if (X_IN_BOUNDS(scr, view, nx) && Y_IN_BOUNDS(scr, view, ny)) { - view->x_offset = nx; - view->y_offset = ny; - view->zoom = zoom; - } -} +#if defined SEKIHI_WINDOW_WAYLAND +#define SCROLL_MULTIPLIER 87.5 +#else +#define SCROLL_MULTIPLIER 5.0 +#endif -static void scroll_callback(void *userdata, f64 y) +static bool scroll_callback(void *userdata, f64 y) { struct camu_screen *scr = (struct camu_screen *)userdata; - struct camu_view *view = get_view_from_mouse_pos(scr); - if (!view) return; - - if (scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE) { - y = -y; -#if defined SEKIHI_WINDOW_GLFW - y /= 4.5; -#elif defined SEKIHI_WINDOW_WAYLAND - y /= 100.0; -#else - y /= 14.0; -#endif - zoom_on_point(scr, view, scr->last_mouse_x, scr->last_mouse_y, y); - view->mode = CAMU_VIEW_DETACHED; + if (view && scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE) { + y = -y / SCROLL_MULTIPLIER; + if (camu_view_zoom_simple(view, scr->width, scr->height, scr->last_mouse_x, scr->last_mouse_y, y)) { + view->mode = CAMU_VIEW_DETACHED; + return true; + } } + return false; } -static void key_callback(void *userdata, u8 state, u8 button) +static bool key_callback(void *userdata, u8 state, u8 button) { struct camu_screen *scr = (struct camu_screen *)userdata; switch (state) { @@ -183,9 +145,11 @@ static void key_callback(void *userdata, u8 state, u8 button) case 0x1b: case 'r': { struct camu_view *view = get_view_from_mouse_pos(scr); - if (!view) return; - view->mode = CAMU_DEFAULT_VIEW; - camu_view_calculate(view, scr->width, scr->height); + if (view) { + view->mode = CAMU_DEFAULT_VIEW; + camu_view_calculate(view, scr->width, scr->height); + return true; + } break; } case 0x1d: @@ -204,6 +168,7 @@ static void key_callback(void *userdata, u8 state, u8 button) default: break; } + return false; } static void key_immediate_callback(void *userdata, u8 state, u8 button) @@ -251,7 +216,8 @@ bool camu_screen_init(struct camu_screen *scr) bool camu_screen_create_window(struct camu_screen *scr, const char *name) { - if (!scr->window->create_window(scr->window, CAMU_SCREEN_WIDTH, CAMU_SCREEN_HEIGHT, name)) { + s32 flags = SEKIHI_WINDOW_VSYNC; + if (!scr->window->create_window(scr->window, CAMU_SCREEN_WIDTH, CAMU_SCREEN_HEIGHT, NULL, name, flags)) { return false; } scr->width = scr->window->width; @@ -263,14 +229,13 @@ bool camu_screen_create_renderer(struct camu_screen *scr, struct camu_renderer * { scr->renderer = renderer; return renderer->create_renderer(renderer, &scr->width, &scr->height, - scr->window->poll, #if defined CAMU_RENDERER_VULKAN scr->window->get_vk_proc_address, scr->window->vk_create_surface, scr->window->vk_get_extensions, #elif defined CAMU_RENDERER_OPENGL scr->window->get_gl_proc_address, - scr->window->gl_load_loader, + scr->window->gl_loader_load, scr->window->gl_make_current, scr->window->gl_release_current, scr->window->gl_swap_buffers, @@ -367,28 +332,30 @@ void camu_screen_run_queue(struct camu_screen *scr) } #endif -void camu_screen_set_state(struct camu_screen *scr, u8 state) +void camu_screen_set_state(struct camu_screen *scr, s32 state) { al_atomic_s32_store(&scr->state, state, AL_ATOMIC_RELAXED); } -bool camu_screen_tick(struct camu_screen *scr) +bool camu_screen_poll(struct camu_screen *scr, bool block) { -#if defined SEKIHI_POLL_CONSERVATIVE - scr->window->poll(scr->window, - al_atomic_s32_load(&scr->state, AL_ATOMIC_RELAXED) == CAMU_SCREEN_PAUSED); - return skh_window_read_events(scr->window); -#elif defined SEKIHI_POLL_INLINE - return scr->window->poll(scr->window, - al_atomic_s32_load(&scr->state, AL_ATOMIC_RELAXED) == CAMU_SCREEN_PAUSED); + scr->window->poll(scr->window, block); + scr->window->process_events(scr->window); +#if defined SEKIHI_EVENT_BUFFER + skh_window_read_events(scr->window); #endif + return scr->window->should_refresh(scr->window); +} + +bool camu_screen_tick(struct camu_screen *scr) +{ + bool paused = al_atomic_s32_load(&scr->state, AL_ATOMIC_RELAXED) == CAMU_SCREEN_PAUSED; + return camu_screen_poll(scr, paused) || !paused; } void camu_screen_wake(struct camu_screen *scr) { -#ifdef SEKIHI_PAUSE scr->window->wake(scr->window); -#endif } void camu_screen_close(struct camu_screen *scr) @@ -399,4 +366,5 @@ void camu_screen_close(struct camu_screen *scr) aki_mutex_destroy(&scr->mutex); #endif al_array_free(scr->videos); + scr->window->free(&scr->window); } diff --git a/src/screen/screen.h b/src/screen/screen.h index 798fc8e..0ca5779 100644 --- a/src/screen/screen.h +++ b/src/screen/screen.h @@ -19,9 +19,9 @@ #define CAMU_SCREEN_HEIGHT 700 enum { - CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1, + CAMU_SCREEN_MODIFIER = 1, CAMU_SCREEN_DRAGGING = 1 << 1, - CAMU_SCREEN_MODIFIER = 1 << 2, + CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1 << 2, }; enum { @@ -72,7 +72,8 @@ void camu_screen_remove_buffer(struct camu_screen *scr, struct camu_video_buffer #ifdef CAMU_SCREEN_THREADED void camu_screen_run_queue(struct camu_screen *scr); #endif -void camu_screen_set_state(struct camu_screen *scr, u8 state); +void camu_screen_set_state(struct camu_screen *scr, s32 state); +bool camu_screen_poll(struct camu_screen *scr, bool block); bool camu_screen_tick(struct camu_screen *scr); void camu_screen_wake(struct camu_screen *scr); void camu_screen_close(struct camu_screen *scr); diff --git a/src/screen/view.c b/src/screen/view.c index cf23ed4..4cf6007 100644 --- a/src/screen/view.c +++ b/src/screen/view.c @@ -1,5 +1,15 @@ #include "view.h" +#define ZOOM_MAX 100.0 +#define ZOOM_MIN 0.02 + +#define PAN_BOUNDS 35.0 + +#define X_IN_BOUNDS(view, w, x) \ + ((x + PAN_BOUNDS <= w) && (PAN_BOUNDS - x <= view->width * view->zoom)) +#define Y_IN_BOUNDS(view, h, y) \ + ((y + PAN_BOUNDS <= h) && (PAN_BOUNDS - y <= view->height * view->zoom)) + void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_height) { f64 ratio = window_width / (f64)window_height; @@ -26,3 +36,48 @@ void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_he view->x_offset = ((window_width - (view->width * view->zoom)) / 2.0); view->y_offset = ((window_height - (view->height * view->zoom)) / 2.0); } + +bool camu_view_pan_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 dx, f64 dy) +{ + f64 nx = view->x_offset + dx; + f64 ny = view->y_offset + dy; + bool view_changed = false; + if (X_IN_BOUNDS(view, window_width, nx)) { + view->x_offset = nx; + view_changed = true; + } + if (Y_IN_BOUNDS(view, window_height, ny)) { + view->y_offset = ny; + view_changed = true; + } + return view_changed; +} + +bool camu_view_zoom_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 x, f64 y, f64 v) +{ + x -= view->x_offset; + y -= view->y_offset; + x /= view->zoom; + y /= view->zoom; + + f64 prev_width = window_width * view->zoom; + f64 prev_height = window_height * view->zoom; + + f64 x_ratio = x / (f64)window_width; + f64 y_ratio = y / (f64)window_height; + + f64 zoom = view->zoom + (v * view->zoom); + if (zoom > ZOOM_MAX || zoom < ZOOM_MIN) return false; + + x = view->x_offset - x_ratio * ((window_width * zoom) - prev_width); + y = view->y_offset - y_ratio * ((window_height * zoom) - prev_height); + if (!(X_IN_BOUNDS(view, window_width, x) && Y_IN_BOUNDS(view, window_height, y))) { + return false; + } + + view->x_offset = x; + view->y_offset = y; + view->zoom = zoom; + + return true; +} diff --git a/src/screen/view.h b/src/screen/view.h index 0546062..e9bec81 100644 --- a/src/screen/view.h +++ b/src/screen/view.h @@ -9,6 +9,8 @@ enum { CAMU_VIEW_DETACHED }; +#define CAMU_DEFAULT_VIEW CAMU_VIEW_AUTOFIT + struct camu_view { u8 mode; s32 width; @@ -21,3 +23,5 @@ struct camu_view { }; void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_height); +bool camu_view_pan_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 dx, f64 dy); +bool camu_view_zoom_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 x, f64 y, f64 v); |