summaryrefslogtreecommitdiff
path: root/src/screen
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen')
-rw-r--r--src/screen/screen.c208
-rw-r--r--src/screen/screen.h31
2 files changed, 197 insertions, 42 deletions
diff --git a/src/screen/screen.c b/src/screen/screen.c
index c0527c3..ae9b001 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -24,6 +24,8 @@
#define SCREEN_LAST_CLICK_WITHIN(ns) \
(((scr)->last_click_ts != SCREEN_INVALID_TS) && (nn_get_timestamp() - (scr)->last_click_ts <= ns))
+#define SCREEN_OSD_BAR_HEIGHT 15
+
static void should_close_callback(void *userdata)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
@@ -62,15 +64,15 @@ static void resize_callback(void *userdata, u32 width, u32 height)
do_resize(scr, width, height);
}
+// @TODO: Incomplete.
static struct camu_view *get_view_from_mouse_pos(struct camu_screen *scr)
{
struct camu_view *view = NULL;
+ if (scr->videos.count > 0) {
+ view = &al_array_last(scr->videos).view;
+ }
struct camu_screen_video *video;
al_array_foreach_ptr(scr->videos, i, video) {
- if (!view) {
- view = &video->view;
- continue;
- }
if (view->zindex < video->view.zindex) {
view = &video->view;
}
@@ -85,21 +87,26 @@ static void seek_to_percent_at_pointer(struct camu_screen *scr, f64 x)
scr->callback(scr->userdata, CAMU_SCREEN_PERCENT_SEEK, &percent);
}
-static bool pointer_pos_callback(void *userdata, f64 x, f64 y)
+static bool pointer_callback(void *userdata, u8 type, 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 (SCREEN_IS_DRAGGING(scr)) {
-#ifdef CAMU_SCREEN_DRAG_SEEK
- u64 now = nn_get_timestamp();
- if (view && now - scr->last_seek_ts > 100000) {
- seek_to_percent_at_pointer(scr, x);
- scr->last_seek_ts = now;
+ bool have_pointer_move = scr->window->flags & STELA_WINDOW_SUPPORTS_POINTER_MOVE;
+ switch (type) {
+ case STELA_POINTER_POS:
+ if (scr->vr_emulation && have_pointer_move) {
+ break;
}
+ if (SCREEN_IS_DRAGGING(scr)) {
+#ifdef CAMU_SCREEN_DRAG_SEEK
+ u64 now = nn_get_timestamp();
+ if (view && now - scr->last_seek_ts > 100000) {
+ seek_to_percent_at_pointer(scr, x);
+ scr->last_seek_ts = now;
+ }
#else
- if (view) {
- if (SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) {
+ if (view && !SCREEN_MOD1(scr) && SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) {
f64 dx = x - scr->last_pointer_x;
f64 dy = y - scr->last_pointer_y;
if (camu_view_pan_simple(view, scr->width, scr->height, dx, dy)) {
@@ -110,11 +117,26 @@ static bool pointer_pos_callback(void *userdata, f64 x, f64 y)
scr->last_click_ts = SCREEN_INVALID_TS;
}
}
- }
#endif
+ }
+ if (SCREEN_MOD1(scr) && scr->osd.duration > 0) {
+ f64 dx = x - scr->last_pointer_x;
+ if (fabs(dx) >= 2.0 || y >= scr->height - SCREEN_OSD_BAR_HEIGHT) {
+ scr->osd.bar_mode = CAMU_OSD_BAR_SEEK;
+ }
+ }
+ scr->last_pointer_x = x;
+ scr->last_pointer_y = y;
+ break;
+ case STELA_POINTER_MOVE:
+ if (!scr->vr_emulation || !have_pointer_move) {
+ break;
+ }
+ scr->last_pointer_x += x * 0.75f;
+ scr->last_pointer_y += y * 0.75f;
+ queue_refresh = true;
+ break;
}
- scr->last_pointer_x = x;
- scr->last_pointer_y = y;
return queue_refresh;
}
@@ -169,7 +191,7 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y)
f64 lx = scr->last_touch_x[0], lx2 = scr->last_touch_x[1];
f64 ly = scr->last_touch_y[0], ly2 = scr->last_touch_y[1];
f64 dist = distance(lx, lx2, ly, ly2);
- f64 mx = x = (lx + lx2) / 2.0, my = (ly + ly2) / 2.0;
+ f64 mx = (lx + lx2) / 2.0, my = (ly + ly2) / 2.0;
bool refresh = false;
struct camu_view *view = get_view_from_mouse_pos(scr);
if (view) {
@@ -190,7 +212,7 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y)
scr->last_pointer_x = scr->last_touch_x[1];
scr->last_pointer_y = scr->last_touch_y[1];
}
- bool refresh = pointer_pos_callback(scr, x, y);
+ bool refresh = pointer_callback(scr, STELA_POINTER_POS, x, y);
if (index == 0) {
scr->last_touch_x[0] = x;
scr->last_touch_y[0] = y;
@@ -213,7 +235,12 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y)
if (SCREEN_LAST_CLICK_WITHIN(200000)) {
f64 third = scr->width / 3.0;
if (x >= third && x <= third * 2.0) {
- scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
+ if (scr->vr_emulation) {
+ scr->vr_calibrate_x = scr->last_pointer_x / scr->width;
+ scr->vr_calibrate_y = scr->last_pointer_y / scr->height;
+ } else {
+ scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
+ }
} else {
if (scr->touch_mode) {
#if CAMU_HAVE_SUBTITLES
@@ -246,7 +273,8 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button)
break;
case STELA_BUTTON_RELEASED:
scr->flags &= ~CAMU_SCREEN_DRAGGING;
- scr->window->set_cursor(scr->window, SCREEN_MOUSE_MOD(scr) ? STELA_CURSOR_CROSSHAIR : SCREEN_DEFAULT_CURSOR(scr));
+ bool want_crosshair = SCREEN_MOUSE_MOD(scr) && scr->fullscreen;
+ scr->window->set_cursor(scr->window, want_crosshair ? STELA_CURSOR_CROSSHAIR : SCREEN_DEFAULT_CURSOR(scr));
if (SCREEN_LAST_CLICK_WITHIN(200000)) {
if (SCREEN_MOD1(scr)) {
seek_to_percent_at_pointer(scr, scr->last_pointer_x);
@@ -295,6 +323,9 @@ bool scroll_callback(void *userdata, f64 y)
if (SCREEN_MOD1(scr)) {
f32 change = (f32)stl_scale_scroll(y, 40.0);
scr->callback(scr->userdata, CAMU_SCREEN_OFFSET_VOLUME, &change);
+ scr->osd.bar_mode = CAMU_OSD_BAR_VOLUME;
+ scr->osd.bar = change;
+ return true;
} else {
struct camu_view *view = get_view_from_mouse_pos(scr);
if (view) {
@@ -321,14 +352,21 @@ static bool key_callback(void *userdata, u8 state, u16 button)
scr->window->close(scr->window);
scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL);
break;
+ case STELA_KEY_SLASH:
+ scr->osd.show_binds = !scr->osd.show_binds;
+ break;
case STELA_KEY_RIGHT:
if (SCREEN_MOD1(scr)) {
- f64 plus_ten_seconds = 10.0;
- scr->callback(scr->userdata, CAMU_SCREEN_RELATIVE_SEEK, &plus_ten_seconds);
+ if (SCREEN_MOD2(scr)) {
+ f64 one_hundred = 100.0;
+ scr->callback(scr->userdata, CAMU_SCREEN_PERCENT_SEEK, &one_hundred);
+ } else {
+ f64 plus_ten_seconds = 10.0;
+ scr->callback(scr->userdata, CAMU_SCREEN_RELATIVE_SEEK, &plus_ten_seconds);
+ }
break;
}
// fallthrough
- case STELA_KEY_TAB:
case STELA_KEY_D: {
s32 n = 1;
scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
@@ -351,6 +389,31 @@ static bool key_callback(void *userdata, u8 state, u16 button)
scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
break;
}
+ case STELA_KEY_LEFT_CONTROL:
+ case STELA_KEY_RIGHT_CONTROL:
+ if (scr->osd.shown_for & CAMU_OSD_VOLUME) {
+ scr->osd.shown_for &= ~CAMU_OSD_VOLUME;
+ scr->osd.shown_for |= CAMU_OSD_SEEK;
+ } else if (!scr->osd.show) {
+ scr->osd.show = true;
+ scr->osd.shown_for |= CAMU_OSD_SEEK;
+ }
+ if (scr->last_pointer_y >= scr->height - SCREEN_OSD_BAR_HEIGHT) {
+ scr->osd.bar_mode = CAMU_OSD_BAR_SEEK;
+ }
+ break;
+ case STELA_KEY_TAB:
+ if (!(scr->osd.shown_for & CAMU_OSD_SEEK)) {
+ if (scr->osd.flash >= 0.0) {
+ scr->osd.flash = 0.0;
+ } else {
+ scr->osd.show = !scr->osd.show;
+ scr->osd.shown_for = 0;
+ atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
+ }
+ return true;
+ }
+ break;
case STELA_KEY_SPACE:
scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
break;
@@ -366,22 +429,22 @@ static bool key_callback(void *userdata, u8 state, u16 button)
}
break;
case STELA_KEY_E:
- if (scr->vr_emulation) {
- if (scr->vr_emulation == CAMU_VR_180) {
- scr->vr_left_eye = !scr->vr_left_eye;
- log_info(scr->vr_left_eye ? "Left eye." : "Right eye.");
- }
- } else {
- scr->callback(scr->userdata, CAMU_SCREEN_RESEEK, NULL);
- }
+ scr->callback(scr->userdata, CAMU_SCREEN_RESEEK, NULL);
break;
case STELA_KEY_M: {
- f32 volume = SCREEN_MOD1(scr) ? 1.f : -1.f;
+ f32 volume = SCREEN_MOD2(scr) ? 1.f : -1.f;
scr->callback(scr->userdata, CAMU_SCREEN_SET_VOLUME, &volume);
+ scr->osd.bar_mode = CAMU_OSD_BAR_VOLUME;
+ scr->osd.bar = volume;
+ scr->osd.flash = CAMU_OSD_FLASH_FOR(0.75);
+ if (!scr->osd.show) {
+ scr->osd.show = true;
+ scr->osd.shown_for |= CAMU_OSD_VOLUME;
+ }
break;
}
case STELA_KEY_0:
- scr->callback(scr->userdata, CAMU_SCREEN_STATUS, NULL);
+ scr->callback(scr->userdata, CAMU_SCREEN_PRINT, NULL);
break;
#ifdef CAMU_SCREEN_DEBUG_KEY
case STELA_KEY_P:
@@ -504,9 +567,14 @@ static bool key_callback(void *userdata, u8 state, u16 button)
scr->vr_emulation = CAMU_VR_DISABLED;
log_info("VR disabled.");
}
- if (view) {
- camu_view_calculate(view, scr->width, scr->height);
- }
+ if (view) camu_view_calculate(view, scr->width, scr->height);
+ }
+ break;
+ }
+ case STELA_KEY_B: {
+ if (scr->vr_emulation == CAMU_VR_180) {
+ scr->vr_left_eye = !scr->vr_left_eye;
+ log_info(scr->vr_left_eye ? "Left eye." : "Right eye.");
}
break;
}
@@ -515,6 +583,17 @@ static bool key_callback(void *userdata, u8 state, u16 button)
}
break;
case STELA_BUTTON_RELEASED:
+ switch (button) {
+ case STELA_KEY_LEFT_CONTROL:
+ case STELA_KEY_RIGHT_CONTROL:
+ if (scr->osd.shown_for & CAMU_OSD_SEEK) {
+ scr->osd.shown_for &= ~CAMU_OSD_SEEK;
+ scr->osd.show = false;
+ atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
+ }
+ scr->osd.bar_mode = CAMU_OSD_BAR_PROGRESS;
+ return true;
+ }
break;
default:
break;
@@ -529,11 +608,10 @@ static bool key_immediate_callback(void *userdata, u8 state, u16 button)
case STELA_BUTTON_PRESSED:
switch (button) {
case STELA_KEY_F:
- scr->fullscreen = !scr->fullscreen;
// On X11 and Wayland, MOUSE2 will be forcefully released when entering fullscreen.
- if (!SCREEN_MOUSE_MOD(scr)) {
- scr->window->set_cursor(scr->window, scr->fullscreen ? STELA_CURSOR_HIDDEN : STELA_CURSOR_NORMAL);
- }
+ scr->fullscreen = !scr->fullscreen;
+ bool want_crosshair = SCREEN_MOUSE_MOD(scr) && scr->fullscreen;
+ scr->window->set_cursor(scr->window, want_crosshair ? STELA_CURSOR_CROSSHAIR : SCREEN_DEFAULT_CURSOR(scr));
//#ifdef STELA_API_DX11
#if 0 // Stela's window_win32 fullscreen mode (borderless) is likely more desirable here.
scr->renderer->set(scr->renderer, CAMU_RENDERER_FULLSCREEN, scr->fullscreen);
@@ -563,18 +641,29 @@ static bool key_immediate_callback(void *userdata, u8 state, u16 button)
return false;
}
+#ifdef STELA_DRAG_AND_DROP
+static void drag_and_drop_callback(void *userdata, str *path)
+{
+ struct camu_screen *scr = (struct camu_screen *)userdata;
+ scr->callback(scr->userdata, CAMU_SCREEN_ADD, path);
+}
+#endif
+
bool camu_screen_init(struct camu_screen *scr)
{
atomic_store(s32)(&scr->state, CAMU_SCREEN_PAUSED, AL_ATOMIC_RELAXED);
scr->window = stl_window_create();
scr->window->render_callback = render_callback;
scr->window->resize_callback = resize_callback;
- scr->window->pointer_pos_callback = pointer_pos_callback;
+ scr->window->pointer_callback = pointer_callback;
scr->window->touch_callback = touch_callback;
scr->window->scroll_callback = scroll_callback;
scr->window->mouse_button_callback = mouse_button_callback;
scr->window->key_callback = key_callback;
scr->window->key_immediate_callback = key_immediate_callback;
+#ifdef STELA_DRAG_AND_DROP
+ scr->window->drag_and_drop_callback = drag_and_drop_callback;
+#endif
scr->window->should_close_callback = should_close_callback;
scr->window->userdata = scr;
scr->renderer = NULL;
@@ -592,6 +681,9 @@ bool camu_screen_init(struct camu_screen *scr)
scr->last_seek_ts = 0;
#endif
scr->touch_mode = false;
+ scr->osd.show_binds = false;
+ scr->osd.bar = -1.0;
+ scr->osd.flash = -1.0;
scr->vr_emulation = CAMU_VR_DISABLED;
scr->vr_left_eye = false;
scr->vr_calibrate_x = 0.5;
@@ -849,7 +941,9 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force)
{
s32 state = atomic_load(s32)(&scr->state, AL_ATOMIC_RELAXED);
u32 force_refresh = atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE);
- bool paused = !scr->vr_emulation && state == CAMU_SCREEN_PAUSED && force_refresh == 0;
+ bool paused = state == CAMU_SCREEN_PAUSED && force_refresh == 0;
+ paused &= !scr->osd.show;
+ paused &= !scr->vr_emulation;
bool do_render = camu_screen_poll(scr, paused) || !paused;
force_refresh = atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE);
do_render |= force_refresh > 0;
@@ -858,6 +952,36 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force)
if (force_refresh > 0) {
atomic_sub(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELEASE);
}
+ bool was_paused = scr->osd.paused;
+ scr->callback(scr->userdata, CAMU_SCREEN_STATUS, &scr->osd);
+ if (!SCREEN_MOD1(scr)) {
+ if (scr->osd.flash >= 0.0) {
+ if (nn_get_tick() >= scr->osd.flash) {
+ scr->osd.flash = -1.0;
+ scr->osd.shown_for = 0;
+ scr->osd.show = false;
+ scr->osd.bar_mode = CAMU_OSD_BAR_PROGRESS;
+ *force = true;
+ } else {
+ scr->osd.show = true;
+ }
+ }
+ }
+ if (scr->osd.bar_mode == CAMU_OSD_BAR_SEEK) {
+ f64 percent = scr->last_pointer_x / scr->width;
+ scr->osd.bar = CLAMP(percent, 0.0, 100.0);
+ }
+ if (was_paused != scr->osd.paused) {
+ if (scr->osd.paused && !scr->osd.show) {
+ scr->osd.show = true;
+ scr->osd.shown_for |= CAMU_OSD_PAUSE;
+ } else if (scr->osd.shown_for & CAMU_OSD_PAUSE) {
+ scr->osd.shown_for &= ~CAMU_OSD_PAUSE;
+ scr->osd.show = false;
+ }
+ *force = true;
+ }
+ *force |= scr->osd.show;
return do_render;
}
diff --git a/src/screen/screen.h b/src/screen/screen.h
index 0d40a02..c3dcd7d 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -39,6 +39,7 @@ enum {
enum {
CAMU_SCREEN_SET_VOLUME = 0, // f32
CAMU_SCREEN_OFFSET_VOLUME, // f32
+ CAMU_SCREEN_ADD, // str
CAMU_SCREEN_SKIP, // s32
CAMU_SCREEN_TOGGLE_PAUSE,
CAMU_SCREEN_PERCENT_SEEK, // f64
@@ -46,6 +47,7 @@ enum {
CAMU_SCREEN_RESEEK,
CAMU_SCREEN_SHUFFLE,
CAMU_SCREEN_STATUS,
+ CAMU_SCREEN_PRINT,
#ifdef CAMU_SCREEN_DEBUG_KEY
CAMU_SCREEN_DEBUG,
#endif
@@ -57,6 +59,34 @@ struct camu_screen_video {
struct camu_video_buffer *buf;
};
+enum {
+ CAMU_OSD_PAUSE = 1,
+ CAMU_OSD_SEEK = 1 << 1,
+ CAMU_OSD_VOLUME = 1 << 2,
+ CAMU_OSD_EMPTY = 1 << 3
+};
+
+enum {
+ CAMU_OSD_BAR_PROGRESS = 0,
+ CAMU_OSD_BAR_SEEK,
+ CAMU_OSD_BAR_VOLUME
+};
+
+#define CAMU_OSD_FLASH_FOR(s) (nn_get_tick() + s)
+
+struct camu_osd {
+ u32 show;
+ u8 shown_for;
+ bool show_binds;
+ u32 connecting;
+ u32 paused;
+ u32 bar_mode;
+ f64 bar;
+ f64 flash;
+ f64 pts;
+ u64 duration;
+};
+
struct camu_screen {
atomic(s32) state;
struct stl_window *window;
@@ -86,6 +116,7 @@ struct camu_screen {
u64 last_seek_ts;
#endif
bool touch_mode;
+ struct camu_osd osd;
u8 vr_emulation;
bool vr_left_eye;
f64 vr_calibrate_x;