From b0bd93cbc18032dde6abb42cbc3068e906622e48 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 13 Dec 2013 00:19:17 +0100 Subject: dvdnav: support mouse interaction --- etc/input.conf | 3 ++- mpvcore/player/dvdnav.c | 19 ++++++++++++++++--- sub/osd.c | 17 +++++++++++++++++ sub/osd.h | 3 +++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/etc/input.conf b/etc/input.conf index 5c000bcd60..fa0db45e28 100644 --- a/etc/input.conf +++ b/etc/input.conf @@ -200,7 +200,8 @@ #LEFT {dvdnav-menu} dvdnav left # DVDNav LEFT #RIGHT {dvdnav-menu} dvdnav right # DVDNav RIGHT #ENTER {dvdnav-menu} dvdnav select # DVDNav SELECT (ok) -#MOUSE_MOVE {dvdnav-menu} ignore # block mouse events +#MOUSE_BTN0 {dvdnav-menu} dvdnav mouse +#MOUSE_MOVE {dvdnav-menu} dvdnav mouse_move # # Not assigned by default diff --git a/mpvcore/player/dvdnav.c b/mpvcore/player/dvdnav.c index 879bacd1c1..6efa786996 100644 --- a/mpvcore/player/dvdnav.c +++ b/mpvcore/player/dvdnav.c @@ -100,9 +100,22 @@ void mp_nav_user_input(struct MPContext *mpctx, char *command) struct mp_nav_state *nav = mpctx->nav_state; if (!nav) return; - struct mp_nav_cmd inp = {MP_NAV_CMD_MENU}; - inp.u.menu.action = command; - stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp); + if (strcmp(command, "mouse_move") == 0) { + struct mp_image_params vid = {0}; + if (mpctx->d_video) + vid = mpctx->d_video->decoder_output; + struct mp_nav_cmd inp = {MP_NAV_CMD_MOUSE_POS}; + int x, y; + mp_input_get_mouse_pos(mpctx->input, &x, &y); + osd_coords_to_video(mpctx->osd, vid.w, vid.h, &x, &y); + inp.u.mouse_pos.x = x; + inp.u.mouse_pos.y = y; + stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp); + } else { + struct mp_nav_cmd inp = {MP_NAV_CMD_MENU}; + inp.u.menu.action = command; + stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp); + } } void mp_handle_nav(struct MPContext *mpctx) diff --git a/sub/osd.c b/sub/osd.c index ab3764cb00..a1daa1b390 100644 --- a/sub/osd.c +++ b/sub/osd.c @@ -325,6 +325,23 @@ void osd_object_get_scale_factor(struct osd_state *osd, struct osd_object *obj, *sh = nh / (double)obj->vo_res.h; } +// Turn *x and *y, which are given in OSD coordinates, to video coordinates. +// frame_w and frame_h give the dimensions of the original, unscaled video. +// (This gives correct results only after the OSD has been updated after a +// resize or video reconfig.) +void osd_coords_to_video(struct osd_state *osd, int frame_w, int frame_h, + int *x, int *y) +{ + struct mp_osd_res res = osd->objs[OSDTYPE_OSD]->vo_res; + int vidw = res.w - res.ml - res.mr; + int vidh = res.h - res.mt - res.mb; + double xscale = (double)vidw / frame_w; + double yscale = (double)vidh / frame_h; + // The OSD size + margins make up the scaled rectangle of the video. + *x = (*x - res.ml) / xscale; + *y = (*y - res.mt) / yscale; +} + // Position the subbitmaps in imgs on the screen. Basically, this fits the // subtitle canvas (of size frame_w x frame_h) onto the screen, such that it // fills the whole video area (especially if the video is magnified, e.g. on diff --git a/sub/osd.h b/sub/osd.h index 75536f6692..6399804288 100644 --- a/sub/osd.h +++ b/sub/osd.h @@ -235,6 +235,9 @@ void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res, void osd_object_get_scale_factor(struct osd_state *osd, struct osd_object *obj, double *sw, double *sh); +void osd_coords_to_video(struct osd_state *osd, int frame_w, int frame_h, + int *x, int *y); + void osd_rescale_bitmaps(struct sub_bitmaps *imgs, int frame_w, int frame_h, struct mp_osd_res res, double compensate_par); -- cgit v1.2.3