summaryrefslogtreecommitdiff
path: root/src/screen
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen')
-rw-r--r--src/screen/screen.c158
-rw-r--r--src/screen/screen.h14
-rw-r--r--src/screen/view.c29
-rw-r--r--src/screen/view.h15
4 files changed, 122 insertions, 94 deletions
diff --git a/src/screen/screen.c b/src/screen/screen.c
index b4f65c2..cb49188 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -5,6 +5,8 @@
#include "view.h"
#include "screen.h"
+#define SCREEN_INVALID_TS ((u64)-1)
+
static struct camu_view *get_view_from_mouse_pos(struct camu_screen *scr)
{
struct camu_view *view = NULL;
@@ -27,24 +29,20 @@ static void should_close_callback(void *userdata)
scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL);
}
-static void resize_callback(void *userdata, s32 width, s32 height)
+static void resize_callback(void *userdata, u32 width, u32 height)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
- bool fullscreen = scr->window->fullscreen;
if (scr->renderer) {
- // Checking if window->fullscreen changed here relies on the order of resize events.
- // If it's possible for a different resize to be buffered before the resize
- // of the fullscreen toggle, this may not work as expected.
- scr->renderer->resize(scr->renderer, &width, &height, fullscreen != scr->last_fullscreen);
+ scr->renderer->resize(scr->renderer, &width, &height);
}
- scr->width = width;
- scr->height = height;
- scr->last_fullscreen = fullscreen;
+ al_assert(width > 0 && height > 0);
+ scr->width = (u32)width;
+ scr->height = (u32)height;
struct camu_screen_video *video;
al_array_foreach_ptr(scr->videos, i, video) {
camu_view_calculate(&video->view, scr->width, scr->height);
}
- scr->force_refresh = true;
+ al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
}
static void refresh_callback(void *userdata)
@@ -68,26 +66,25 @@ 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_MODIFIER) &&
- (scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE)) {
- 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;
- }
- if (fabs(dx) + fabs(dy) > 3.0) scr->last_click_ts = 0;
- } else {
- u64 now = nn_get_timestamp();
- if (!scr->last_click_ts) {
- scr->last_click_ts = now;
- }
- if (now - scr->last_seek_ts > 100000) {
- scr->last_seek_ts = now;
- seek_to_percent_at_pointer(scr);
- }
+ if (scr->flags & CAMU_SCREEN_DRAGGING) {
+ if (scr->flags & CAMU_SCREEN_MOD_CONTROL) {
+ u64 now = nn_get_timestamp();
+ if (scr->last_seek_ts == SCREEN_INVALID_TS) {
+ scr->last_seek_ts = now;
+ }
+ if (now - scr->last_seek_ts > 100000) {
+ scr->last_seek_ts = now;
+ seek_to_percent_at_pointer(scr);
+ }
+ } else if (view && scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE) {
+ 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;
+ }
+ if (fabs(dx) + fabs(dy) > 3.0) {
+ scr->last_click_ts = SCREEN_INVALID_TS;
}
}
}
@@ -105,14 +102,17 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button)
case STELA_BUTTON_PRESSED:
scr->flags |= CAMU_SCREEN_DRAGGING;
scr->last_click_ts = nn_get_timestamp();
+ //scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
break;
case STELA_BUTTON_RELEASED:
scr->flags &= ~CAMU_SCREEN_DRAGGING;
- if (scr->last_click_ts && nn_get_timestamp() - scr->last_click_ts <= 300000) {
- if (scr->flags & CAMU_SCREEN_MODIFIER) {
+ //scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
+ if (scr->last_click_ts != SCREEN_INVALID_TS &&
+ (nn_get_timestamp() - scr->last_click_ts <= 300000)) {
+ if (scr->flags & CAMU_SCREEN_MOD_CONTROL) {
seek_to_percent_at_pointer(scr);
} else {
- if (scr->last_mouse_x >= scr->width / 2.f) {
+ if (scr->last_mouse_x >= scr->width / 2.0) {
scr->callback(scr->userdata, CAMU_SCREEN_NEXT, NULL);
} else {
scr->callback(scr->userdata, CAMU_SCREEN_PREVIOUS, NULL);
@@ -125,10 +125,10 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button)
case STELA_MOUSE2:
switch (state) {
case STELA_BUTTON_PRESSED:
- scr->flags |= CAMU_SCREEN_MODIFIER;
+ scr->flags |= CAMU_SCREEN_MOD_CONTROL;
break;
case STELA_BUTTON_RELEASED:
- scr->flags &= ~CAMU_SCREEN_MODIFIER;
+ scr->flags &= ~CAMU_SCREEN_MOD_CONTROL;
break;
}
break;
@@ -157,7 +157,7 @@ static bool scroll_callback(void *userdata, f64 y)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
y = -y / SCROLL_MULTIPLIER;
- if (!(scr->flags & CAMU_SCREEN_MODIFIER)) {
+ if (!(scr->flags & CAMU_SCREEN_MOD_CONTROL)) {
struct camu_view *view = get_view_from_mouse_pos(scr);
if (view) {
if (scr->flags & CAMU_SCREEN_ZOOM_PAN_SIMPLE) {
@@ -180,8 +180,11 @@ static bool key_callback(void *userdata, u8 state, u8 button)
case STELA_BUTTON_PRESSED:
//al_printf("%x\n", button);
switch (button) {
+ case 0x2a: // shift
+ scr->flags |= CAMU_SCREEN_MOD_SHIFT;
+ break;
case 0x1d: // control
- scr->flags |= CAMU_SCREEN_MODIFIER;
+ scr->flags |= CAMU_SCREEN_MOD_CONTROL;
break;
case 0x10: // q
scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL);
@@ -215,9 +218,23 @@ static bool key_callback(void *userdata, u8 state, u8 button)
case 0x13: { // r
struct camu_view *view = get_view_from_mouse_pos(scr);
if (view) {
- if (!(scr->flags & CAMU_SCREEN_MODIFIER)) {
- view->mode = CAMU_DEFAULT_VIEW;
- } else {
+ if (scr->flags & CAMU_SCREEN_MOD_SHIFT) {
+ switch (view->rotation) {
+ case CAMU_VIEW_ROTATION_0:
+ case CAMU_VIEW_ROTATION_360:
+ view->rotation = CAMU_VIEW_ROTATION_90;
+ break;
+ case CAMU_VIEW_ROTATION_270:
+ view->rotation = CAMU_VIEW_ROTATION_0;
+ break;
+ case CAMU_VIEW_ROTATION_180:
+ view->rotation = CAMU_VIEW_ROTATION_270;
+ break;
+ case CAMU_VIEW_ROTATION_90:
+ view->rotation = CAMU_VIEW_ROTATION_180;
+ break;
+ }
+ } else if (scr->flags & CAMU_SCREEN_MOD_CONTROL) {
switch (view->rotation) {
case CAMU_VIEW_ROTATION_0:
case CAMU_VIEW_ROTATION_360:
@@ -233,6 +250,8 @@ static bool key_callback(void *userdata, u8 state, u8 button)
view->rotation = CAMU_VIEW_ROTATION_0;
break;
}
+ } else {
+ view->mode = CAMU_DEFAULT_VIEW;
}
camu_view_calculate(view, scr->width, scr->height);
return true;
@@ -261,8 +280,11 @@ static bool key_callback(void *userdata, u8 state, u8 button)
break;
case STELA_BUTTON_RELEASED:
switch (button) {
+ case 0x2a: // shift
+ scr->flags &= ~CAMU_SCREEN_MOD_SHIFT;
+ break;
case 0x1d: // control
- scr->flags &= ~CAMU_SCREEN_MODIFIER;
+ scr->flags &= ~CAMU_SCREEN_MOD_CONTROL;
break;
}
default:
@@ -279,6 +301,10 @@ static void key_immediate_callback(void *userdata, u8 state, u8 button)
switch (button) {
case 0x21: // f
scr->window->toggle_fullscreen(scr->window);
+ // Least intrusive workaround I can think of for the egl resizing issue.
+ // Will only work for fullscreening, things like toggling floating state
+ // on sway are still broken.
+ al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
break;
}
break;
@@ -301,10 +327,12 @@ bool camu_screen_init(struct camu_screen *scr, void *context)
scr->window->should_close_callback = should_close_callback;
scr->window->userdata = scr;
scr->renderer = NULL;
- scr->force_refresh = false;
+ al_atomic_store(u32)(&scr->force_refresh, 0, AL_ATOMIC_RELAXED);
scr->flags = CAMU_SCREEN_ZOOM_PAN_SIMPLE;
+ scr->last_click_ts = SCREEN_INVALID_TS;
scr->last_mouse_x = 0.0;
scr->last_mouse_y = 0.0;
+ scr->last_seek_ts = SCREEN_INVALID_TS;
al_array_init(scr->videos);
#ifdef CAMU_SCREEN_THREADED
al_array_init(scr->add_queue);
@@ -334,7 +362,6 @@ bool camu_screen_create_window(struct camu_screen *scr, const char *name)
}
scr->width = scr->window->width;
scr->height = scr->window->height;
- scr->last_fullscreen = false;
#ifdef STELA_EVENT_BUFFER
nn_thread_create(&scr->thread, event_thread, scr);
#endif
@@ -365,9 +392,9 @@ bool camu_screen_create_renderer(struct camu_screen *scr, struct camu_renderer *
static void add_buffer_internal(struct camu_screen *scr, struct camu_video_buffer *buf)
{
- struct camu_screen_video *rvideo;
- al_array_foreach_ptr(scr->videos, i, rvideo) {
- al_assert(rvideo->buf != buf);
+ struct camu_screen_video *added;
+ al_array_foreach_ptr(scr->videos, i, added) {
+ al_assert(added->buf != buf);
}
struct camu_screen_video video = {
.buf = buf
@@ -383,17 +410,17 @@ static void add_buffer_internal(struct camu_screen *scr, struct camu_video_buffe
#endif
} else {
video.view.mode = CAMU_DEFAULT_VIEW;
+ video.view.rotation = CAMU_VIEW_ROTATION_0;
video.view.width = fmt->width;
video.view.height = fmt->height;
- video.view.stretch = 1.0;
- video.view.rotation = CAMU_VIEW_ROTATION_0;
video.view.zindex = 0;
+ video.view.stretch = 1.0;
}
camu_view_calculate(&video.view, scr->width, scr->height);
#ifdef CAMU_SCREEN_THREADED
al_atomic_store(u8)(&buf->ref, 1, AL_ATOMIC_RELAXED);
#endif
-
+ //al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
al_array_push(scr->videos, video);
}
@@ -428,7 +455,6 @@ static void run_queue_internal(struct camu_screen *scr)
add_buffer_internal(scr, buf);
}
scr->add_queue.count = 0;
- //scr->force_refresh = scr->videos.count == 0;
}
#endif
@@ -436,15 +462,15 @@ void camu_screen_add_buffer(struct camu_screen *scr, struct camu_video_buffer *b
{
#ifdef CAMU_SCREEN_THREADED
nn_mutex_lock(&scr->mutex);
- struct camu_video_buffer *rbuf;
- al_array_foreach(scr->add_queue, i, rbuf) {
- if (rbuf == buf) {
+ struct camu_video_buffer *queued;
+ al_array_foreach(scr->add_queue, i, queued) {
+ if (queued == buf) {
nn_mutex_unlock(&scr->mutex);
return;
}
}
- al_array_foreach_rev(scr->rem_queue, i, rbuf) {
- if (rbuf == buf) {
+ al_array_foreach_rev(scr->rem_queue, i, queued) {
+ if (queued == buf) {
al_array_remove_at(scr->rem_queue, i);
bool queue_empty = scr->add_queue.count + scr->rem_queue.count == 0;
if (queue_empty) {
@@ -467,15 +493,15 @@ void camu_screen_remove_buffer(struct camu_screen *scr, struct camu_video_buffer
{
#ifdef CAMU_SCREEN_THREADED
nn_mutex_lock(&scr->mutex);
- struct camu_video_buffer *rbuf;
- al_array_foreach(scr->rem_queue, i, rbuf) {
- if (rbuf == buf) {
+ struct camu_video_buffer *queued;
+ al_array_foreach(scr->rem_queue, i, queued) {
+ if (queued == buf) {
nn_mutex_unlock(&scr->mutex);
return;
}
}
- al_array_foreach_rev(scr->add_queue, i, rbuf) {
- if (rbuf == buf) {
+ al_array_foreach_rev(scr->add_queue, i, queued) {
+ if (queued == buf) {
al_array_remove_at(scr->add_queue, i);
bool queue_empty = scr->add_queue.count + scr->rem_queue.count == 0;
if (queue_empty) {
@@ -517,12 +543,13 @@ void camu_screen_clear(struct camu_screen *scr)
void camu_screen_set_state(struct camu_screen *scr, s32 state)
{
+ // @TODO: What to do if a buffer is queued for removal and we pause here.
al_atomic_store(s32)(&scr->state, state, AL_ATOMIC_RELAXED);
}
void camu_screen_force_refresh(struct camu_screen *scr)
{
- scr->force_refresh = true;
+ al_atomic_store(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
camu_screen_wake(scr);
}
@@ -552,9 +579,12 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force)
al_assert(state != CAMU_SCREEN_STOPPED);
bool paused = state == CAMU_SCREEN_PAUSED;
bool do_render = camu_screen_poll(scr, paused) || !paused;
- do_render |= scr->force_refresh;
- *force = scr->force_refresh;
- scr->force_refresh = false;
+ u32 force_refresh = al_atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE);
+ do_render |= force_refresh > 0;
+ *force = force_refresh > 0;
+ if (force_refresh > 0) {
+ al_atomic_store(u32)(&scr->force_refresh, 0, AL_ATOMIC_RELEASE);
+ }
return do_render;
}
diff --git a/src/screen/screen.h b/src/screen/screen.h
index e0d1fc3..0b8ed33 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -18,9 +18,10 @@
#define CAMU_SCREEN_HEIGHT 700
enum {
- CAMU_SCREEN_MODIFIER = 1,
- CAMU_SCREEN_DRAGGING = 1 << 1,
- CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1 << 2
+ CAMU_SCREEN_MOD_SHIFT = 1,
+ CAMU_SCREEN_MOD_CONTROL = 1 << 1,
+ CAMU_SCREEN_DRAGGING = 1 << 2,
+ CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1 << 3
};
enum {
@@ -55,11 +56,10 @@ struct camu_screen {
struct nn_thread thread;
#endif
struct camu_renderer *renderer;
- bool force_refresh;
+ atomic(u32) force_refresh;
u32 flags;
- s32 width;
- s32 height;
- bool last_fullscreen;
+ u32 width;
+ u32 height;
u64 last_click_ts;
f64 last_mouse_y;
f64 last_mouse_x;
diff --git a/src/screen/view.c b/src/screen/view.c
index 0ca5f4c..b5fade2 100644
--- a/src/screen/view.c
+++ b/src/screen/view.c
@@ -15,34 +15,33 @@
#define VIEW_ON_ITS_SIDE(view) \
(view->rotation % CAMU_VIEW_ROTATION_180 == CAMU_VIEW_ROTATION_90)
-void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_height)
+void camu_view_calculate(struct camu_view *view, u32 window_width, u32 window_height)
{
- f64 width, height;
+ u32 width, height;
if (VIEW_ON_ITS_SIDE(view)) {
- width = (f64)view->height;
- height = (f64)view->width;
- view->stretch = height / width;
+ width = view->height;
+ height = view->width;
+ view->stretch = height / (f64)width;
} else {
- width = (f64)view->width;
- height = (f64)view->height;
+ width = view->width;
+ height = view->height;
view->stretch = 1.0;
}
- f64 frame_ratio = width / height;
+ f64 frame_ratio = width / (f64)height;
f64 ratio = window_width / (f64)window_height;
- view->ratio = ratio / frame_ratio;
switch (view->mode) {
case CAMU_VIEW_AUTOFIT:
if (frame_ratio > ratio) {
- view->zoom = window_width / width;
+ view->zoom = window_width / (f64)width;
} else {
- view->zoom = window_height / height;
+ view->zoom = window_height / (f64)height;
}
break;
case CAMU_VIEW_ZOOM:
if (frame_ratio < ratio) {
- view->zoom = window_width / width;
+ view->zoom = window_width / (f64)width;
} else {
- view->zoom = window_height / height;
+ view->zoom = window_height / (f64)height;
}
break;
default:
@@ -52,7 +51,7 @@ void camu_view_calculate(struct camu_view *view, s32 window_width, s32 window_he
view->y_offset = (window_height - (height * view->zoom)) / 2.0;
}
-bool camu_view_pan_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 dx, f64 dy)
+bool camu_view_pan_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 dx, f64 dy)
{
f64 nx = view->x_offset + dx;
f64 ny = view->y_offset + dy;
@@ -68,7 +67,7 @@ bool camu_view_pan_simple(struct camu_view *view, s32 window_width, s32 window_h
return view_changed;
}
-bool camu_view_zoom_simple(struct camu_view *view, s32 window_width, s32 window_height, f64 x, f64 y, f64 v)
+bool camu_view_zoom_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 x, f64 y, f64 v)
{
x -= view->x_offset;
y -= view->y_offset;
diff --git a/src/screen/view.h b/src/screen/view.h
index 8cd3d28..30b6f64 100644
--- a/src/screen/view.h
+++ b/src/screen/view.h
@@ -21,17 +21,16 @@ enum {
struct camu_view {
u8 mode;
- s32 width;
- s32 height;
- f64 ratio;
+ u8 rotation;
+ u32 width;
+ u32 height;
+ s32 zindex;
f64 zoom;
f64 x_offset;
f64 y_offset;
f64 stretch;
- s32 rotation;
- s32 zindex;
};
-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);
+void camu_view_calculate(struct camu_view *view, u32 window_width, u32 window_height);
+bool camu_view_pan_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 dx, f64 dy);
+bool camu_view_zoom_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 x, f64 y, f64 v);