diff --git a/player/client.c b/player/client.c index 8e2bc4d1b7..6a8204615f 100644 --- a/player/client.c +++ b/player/client.c @@ -620,7 +620,7 @@ int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable) { if (!mpv_event_name(event) || enable < 0 || enable > 1) return MPV_ERROR_INVALID_PARAMETER; - assert(event < INTERNAL_EVENT_BASE); // excluded above; they have no name + assert(event < (int)INTERNAL_EVENT_BASE); // excluded above; they have no name pthread_mutex_lock(&ctx->lock); uint64_t bit = 1ULL << event; ctx->event_mask = enable ? ctx->event_mask | bit : ctx->event_mask & ~bit; diff --git a/player/command.c b/player/command.c index aa44196925..391cc5b30a 100644 --- a/player/command.c +++ b/player/command.c @@ -3201,6 +3201,7 @@ static const char *const *const mp_event_property_change[] = { E(MPV_EVENT_CHAPTER_CHANGE, "chapter", "chapter-metadata"), E(MP_EVENT_CACHE_UPDATE, "cache", "cache-free", "cache-used", "cache-idle", "demuxer-cache-duration", "demuxer-cache-idle"), + E(MP_EVENT_WIN_RESIZE, "window-scale"), }; #undef E diff --git a/player/command.h b/player/command.h index 0307bd06b7..3469e32948 100644 --- a/player/command.h +++ b/player/command.h @@ -39,9 +39,13 @@ void mp_notify_property(struct MPContext *mpctx, const char *property); int mp_get_property_id(const char *name); uint64_t mp_get_property_event_mask(const char *name); -// Must start with the first unused positive value in enum mpv_event_id -#define INTERNAL_EVENT_BASE 24 -#define MP_EVENT_CACHE_UPDATE (INTERNAL_EVENT_BASE + 0) +enum { + // Must start with the first unused positive value in enum mpv_event_id + // MPV_EVENT_* and MP_EVENT_* must not overlap. + INTERNAL_EVENT_BASE = 24, + MP_EVENT_CACHE_UPDATE, + MP_EVENT_WIN_RESIZE, +}; bool mp_hook_test_completion(struct MPContext *mpctx, char *type); void mp_hook_run(struct MPContext *mpctx, char *client, char *type); diff --git a/player/playloop.c b/player/playloop.c index 22cc12f70d..85d962fffe 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -670,6 +670,14 @@ static void handle_cursor_autohide(struct MPContext *mpctx) mpctx->mouse_cursor_visible = mouse_cursor_visible; } +static void handle_vo_events(struct MPContext *mpctx) +{ + struct vo *vo = mpctx->video_out; + int events = vo ? vo_query_events(vo, VO_EVENTS_USER, true) : 0; + if (events & VO_EVENT_RESIZE) + mp_notify(mpctx, MP_EVENT_WIN_RESIZE, NULL); +} + void add_frame_pts(struct MPContext *mpctx, double pts) { if (pts == MP_NOPTS_VALUE || mpctx->hrseek_framedrop) { @@ -884,6 +892,7 @@ void run_playloop(struct MPContext *mpctx) } handle_cursor_autohide(mpctx); + handle_vo_events(mpctx); handle_heartbeat_cmd(mpctx); fill_audio_out_buffers(mpctx, endpts); @@ -995,6 +1004,7 @@ void mp_idle(struct MPContext *mpctx) mpctx->sleeptime = 100.0; mp_process_input(mpctx); handle_cursor_autohide(mpctx); + handle_vo_events(mpctx); update_osd_msg(mpctx); handle_osd_redraw(mpctx); } diff --git a/video/out/vo.c b/video/out/vo.c index 9f6021282f..f697002f92 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -129,6 +129,7 @@ struct vo_internal { bool request_redraw; // redraw request from player to VO bool want_redraw; // redraw request from VO to player bool paused; + int queued_events; int64_t flip_queue_offset; // queue flip events at most this much in advance @@ -838,6 +839,31 @@ int64_t vo_get_vsync_interval(struct vo *vo) return vo->in->vsync_interval; } +// Set specific event flags, and wakeup the playback core if needed. +// vo_query_events() can retrieve the events again. +void vo_event(struct vo *vo, int event) +{ + struct vo_internal *in = vo->in; + pthread_mutex_lock(&in->lock); + if ((in->queued_events & event & VO_EVENTS_USER) != (event & VO_EVENTS_USER)) + mp_input_wakeup(vo->input_ctx); + in->queued_events |= event; + pthread_mutex_unlock(&in->lock); +} + +// Check event flags set with vo_event(). Return the mask of events that was +// set and included in the events parameter. If clear==true, clear these events. +int vo_query_events(struct vo *vo, int events, bool clear) +{ + struct vo_internal *in = vo->in; + pthread_mutex_lock(&in->lock); + int r = in->queued_events & events; + if (clear) + in->queued_events &= ~(unsigned)r; + pthread_mutex_unlock(&in->lock); + return r; +} + /** * \brief lookup an integer in a table, table must have 0 as the last key * \param key key to search for diff --git a/video/out/vo.h b/video/out/vo.h index feb2907c67..035b4dc1d6 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -30,10 +30,16 @@ #include "common/common.h" #include "options/options.h" +// VO needs to redraw #define VO_EVENT_EXPOSE 1 +// VO needs to update state to a new window size #define VO_EVENT_RESIZE 2 +// The ICC profile needs to be reloaded #define VO_EVENT_ICC_PROFILE_PATH_CHANGED 4 +// Set of events the player core may be interested in. +#define VO_EVENTS_USER (VO_EVENT_RESIZE) + enum mp_voctrl { /* signal a device reset seek */ VOCTRL_RESET = 1, @@ -298,6 +304,8 @@ void vo_destroy(struct vo *vo); void vo_set_paused(struct vo *vo, bool paused); int64_t vo_get_drop_count(struct vo *vo); int vo_query_format(struct vo *vo, int format); +void vo_event(struct vo *vo, int event); +int vo_query_events(struct vo *vo, int events, bool clear); void vo_set_flip_queue_offset(struct vo *vo, int64_t us); int64_t vo_get_vsync_interval(struct vo *vo); diff --git a/video/out/vo_direct3d.c b/video/out/vo_direct3d.c index 4b81026e35..88575c4e7a 100644 --- a/video/out/vo_direct3d.c +++ b/video/out/vo_direct3d.c @@ -1267,6 +1267,8 @@ static int control(struct vo *vo, uint32_t request, void *data) if (events & VO_EVENT_EXPOSE) vo->want_redraw = true; + vo_event(vo, events); + return r; } diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 3b6e3a2e43..4e1b1a53ea 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -439,6 +439,7 @@ static int control(struct vo *vo, uint32_t request, void *data) get_and_update_icc_profile(vo, p->icc_opts); vo->want_redraw = true; } + vo_event(vo, events); mpgl_unlock(p->glctx); return r; diff --git a/video/out/vo_opengl_old.c b/video/out/vo_opengl_old.c index 87ba48068a..91a14398d5 100644 --- a/video/out/vo_opengl_old.c +++ b/video/out/vo_opengl_old.c @@ -2161,6 +2161,7 @@ static int control(struct vo *vo, uint32_t request, void *data) resize(vo, vo->dwidth, vo->dheight); if (events & VO_EVENT_EXPOSE) vo->want_redraw = true; + vo_event(vo, events); return r; } diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index c904793ca0..822b5009aa 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -561,6 +561,7 @@ static int wait_events(struct vo *vo, int64_t until_time_us) break; case SDL_WINDOWEVENT_SIZE_CHANGED: check_resize(vo); + vo_event(vo, VO_EVENT_RESIZE); break; } break; diff --git a/video/out/vo_vaapi.c b/video/out/vo_vaapi.c index fa23c931c6..89e22d8bbf 100644 --- a/video/out/vo_vaapi.c +++ b/video/out/vo_vaapi.c @@ -567,6 +567,7 @@ static int control(struct vo *vo, uint32_t request, void *data) resize(p); if (events & VO_EVENT_EXPOSE) vo->want_redraw = true; + vo_event(vo, events); return r; } diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index c8836a8639..46190fd032 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -1114,6 +1114,7 @@ static int control(struct vo *vo, uint32_t request, void *data) } else if (events & VO_EVENT_EXPOSE) { vo->want_redraw = true; } + vo_event(vo, events); return r; } diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c index ac6c561526..87e38e45b3 100644 --- a/video/out/vo_wayland.c +++ b/video/out/vo_wayland.c @@ -705,6 +705,8 @@ static int control(struct vo *vo, uint32_t request, void *data) if (events & VO_EVENT_RESIZE) resize(p); + vo_event(vo, events); + return r; } diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index 914522e6b8..38a60c1be8 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -631,6 +631,7 @@ static int control(struct vo *vo, uint32_t request, void *data) int r = vo_x11_control(vo, &events, request, data); if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) resize(vo); + vo_event(vo, events); return r; } diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index 1ea16558ac..07495fb89e 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -851,6 +851,7 @@ static int control(struct vo *vo, uint32_t request, void *data) int r = vo_x11_control(vo, &events, request, data); if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) resize(vo); + vo_event(vo, events); return r; }