mirror of
https://github.com/mpv-player/mpv
synced 2025-02-22 07:46:55 +00:00
vo: different hack for VOs which need to mangle mouse input
Follow up on commit 760548da
. Mouse handling is a bit confusing, because
there are at least 3 coordinate systems associated with it, and it
should be cleaned up. But that is hard, so just apply a hack which gets
the currently-annoying issue (VO backends needing access to the VO) out
of the way.
This commit is contained in:
parent
bc6359313f
commit
89391e7c94
@ -159,6 +159,9 @@ struct input_ctx {
|
||||
// Unlike mouse_x/y, this can be used to resolve mouse click bindings.
|
||||
int mouse_vo_x, mouse_vo_y;
|
||||
|
||||
bool mouse_mangle, mouse_src_mangle;
|
||||
struct mp_rect mouse_src, mouse_dst;
|
||||
|
||||
bool test;
|
||||
|
||||
bool default_bindings;
|
||||
@ -738,11 +741,37 @@ void mp_input_put_axis(struct input_ctx *ictx, int direction, double value)
|
||||
input_unlock(ictx);
|
||||
}
|
||||
|
||||
void mp_input_set_mouse_transform(struct input_ctx *ictx, struct mp_rect *dst,
|
||||
struct mp_rect *src)
|
||||
{
|
||||
input_lock(ictx);
|
||||
ictx->mouse_mangle = dst || src;
|
||||
if (ictx->mouse_mangle) {
|
||||
ictx->mouse_dst = *dst;
|
||||
ictx->mouse_src_mangle = !!src;
|
||||
if (ictx->mouse_src_mangle)
|
||||
ictx->mouse_src = *src;
|
||||
}
|
||||
input_unlock(ictx);
|
||||
}
|
||||
|
||||
void mp_input_set_mouse_pos(struct input_ctx *ictx, int x, int y)
|
||||
{
|
||||
input_lock(ictx);
|
||||
MP_DBG(ictx, "mouse move %d/%d\n", x, y);
|
||||
|
||||
if (ictx->mouse_mangle) {
|
||||
struct mp_rect *src = &ictx->mouse_src;
|
||||
struct mp_rect *dst = &ictx->mouse_dst;
|
||||
x = MPCLAMP(x, dst->x0, dst->x1) - dst->x0;
|
||||
y = MPCLAMP(y, dst->y0, dst->y1) - dst->y0;
|
||||
if (ictx->mouse_src_mangle) {
|
||||
x = x * 1.0 / (dst->x1 - dst->x0) * (src->x1 - src->x0) + src->x0;
|
||||
y = y * 1.0 / (dst->y1 - dst->y0) * (src->y1 - src->y0) + src->y0;
|
||||
}
|
||||
MP_DBG(ictx, "-> %d/%d\n", x, y);
|
||||
}
|
||||
|
||||
ictx->mouse_event_counter++;
|
||||
ictx->mouse_vo_x = x;
|
||||
ictx->mouse_vo_y = y;
|
||||
|
@ -133,6 +133,13 @@ void mp_input_set_mouse_pos(struct input_ctx *ictx, int x, int y);
|
||||
|
||||
void mp_input_get_mouse_pos(struct input_ctx *ictx, int *x, int *y);
|
||||
|
||||
/* Make mp_input_set_mouse_pos() mangle the mouse coordinates. Hack for certain
|
||||
* VOs. dst=NULL, src=NULL reset it. src can be NULL.
|
||||
*/
|
||||
struct mp_rect;
|
||||
void mp_input_set_mouse_transform(struct input_ctx *ictx, struct mp_rect *dst,
|
||||
struct mp_rect *src);
|
||||
|
||||
// As for the cmd one you usually don't need this function.
|
||||
void mp_input_rm_key_fd(struct input_ctx *ictx, int fd);
|
||||
|
||||
|
@ -177,6 +177,7 @@ static struct vo *vo_create(struct mpv_global *global,
|
||||
.max_video_queue = 1,
|
||||
};
|
||||
talloc_steal(vo, log);
|
||||
mp_input_set_mouse_transform(vo->input_ctx, NULL, NULL);
|
||||
if (vo->driver->encode != !!vo->encode_lavc_ctx)
|
||||
goto error;
|
||||
struct m_config *config = m_config_from_obj_desc(vo, vo->log, &desc);
|
||||
@ -415,10 +416,7 @@ void vo_mouse_movement(struct vo *vo, int posx, int posy)
|
||||
{
|
||||
if (!vo->opts->enable_mouse_movements)
|
||||
return;
|
||||
float p[2] = {posx, posy};
|
||||
if (vo->driver->caps & VO_CAP_EVIL_OSD)
|
||||
vo_control(vo, VOCTRL_WINDOW_TO_OSD_COORDS, p);
|
||||
mp_input_set_mouse_pos(vo->input_ctx, p[0], p[1]);
|
||||
mp_input_set_mouse_pos(vo->input_ctx, posx, posy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +71,6 @@ enum mp_voctrl {
|
||||
VOCTRL_SET_DEINTERLACE,
|
||||
VOCTRL_GET_DEINTERLACE,
|
||||
|
||||
VOCTRL_WINDOW_TO_OSD_COORDS, // float[2] (x/y)
|
||||
VOCTRL_GET_WINDOW_SIZE, // int[2] (w/h)
|
||||
VOCTRL_SET_WINDOW_SIZE, // int[2] (w/h)
|
||||
|
||||
@ -134,8 +133,6 @@ struct voctrl_screenshot_args {
|
||||
|
||||
// VO does handle mp_image_params.rotate in 90 degree steps
|
||||
#define VO_CAP_ROTATE90 1
|
||||
// Requires VOCTRL_WINDOW_TO_OSD_COORDS to map mouse coords. to OSD coords.
|
||||
#define VO_CAP_EVIL_OSD 2
|
||||
|
||||
#define VO_MAX_QUEUE 5
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "sub/img_convert.h"
|
||||
|
||||
#include "common/msg.h"
|
||||
#include "input/input.h"
|
||||
|
||||
#include "wayland_common.h"
|
||||
#include "wayland-version.h"
|
||||
@ -501,6 +502,8 @@ static bool resize(struct priv *p)
|
||||
p->dst_w = p->dst.x1 - p->dst.x0;
|
||||
p->dst_h = p->dst.y1 - p->dst.y0;
|
||||
|
||||
mp_input_set_mouse_transform(p->vo->input_ctx, &p->dst, NULL);
|
||||
|
||||
MP_DBG(wl, "resizing %dx%d -> %dx%d\n", wl->window.width,
|
||||
wl->window.height,
|
||||
p->dst_w,
|
||||
@ -898,15 +901,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
return VO_TRUE;
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
return redraw_frame(p);
|
||||
case VOCTRL_WINDOW_TO_OSD_COORDS:
|
||||
{
|
||||
// OSD is rendered into the scaled image
|
||||
float *c = data;
|
||||
struct mp_rect *dst = &p->dst;
|
||||
c[0] = av_clipf(c[0], dst->x0, dst->x1) - dst->x0;
|
||||
c[1] = av_clipf(c[1], dst->y0, dst->y1) - dst->y0;
|
||||
return VO_TRUE;
|
||||
}
|
||||
case VOCTRL_SCREENSHOT:
|
||||
{
|
||||
struct voctrl_screenshot_args *args = data;
|
||||
@ -928,7 +922,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
const struct vo_driver video_out_wayland = {
|
||||
.description = "Wayland SHM video output",
|
||||
.name = "wayland",
|
||||
.caps = VO_CAP_EVIL_OSD,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.preinit = preinit,
|
||||
.query_format = query_format,
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libavutil/common.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "vo.h"
|
||||
@ -53,11 +52,10 @@
|
||||
#include "video/fmt-conversion.h"
|
||||
|
||||
#include "common/msg.h"
|
||||
#include "input/input.h"
|
||||
#include "options/options.h"
|
||||
#include "osdep/timer.h"
|
||||
|
||||
extern int sws_flags;
|
||||
|
||||
struct priv {
|
||||
struct vo *vo;
|
||||
|
||||
@ -340,6 +338,8 @@ static bool resize(struct vo *vo)
|
||||
p->osd.mr = FFMIN(0, p->osd.mr);
|
||||
p->osd.ml = FFMIN(0, p->osd.ml);
|
||||
|
||||
mp_input_set_mouse_transform(vo->input_ctx, &p->dst, NULL);
|
||||
|
||||
p->image_width = (p->dst_w + 7) & (~7);
|
||||
p->image_height = p->dst_h;
|
||||
|
||||
@ -622,14 +622,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
draw_image(vo, p->original_image);
|
||||
return true;
|
||||
case VOCTRL_WINDOW_TO_OSD_COORDS: {
|
||||
// OSD is rendered into the scaled image
|
||||
float *c = data;
|
||||
struct mp_rect *dst = &p->dst;
|
||||
c[0] = av_clipf(c[0], dst->x0, dst->x1) - dst->x0;
|
||||
c[1] = av_clipf(c[1], dst->y0, dst->y1) - dst->y0;
|
||||
return VO_TRUE;
|
||||
}
|
||||
case VOCTRL_SCREENSHOT: {
|
||||
struct voctrl_screenshot_args *args = data;
|
||||
args->out_image = get_screenshot(vo);
|
||||
@ -647,7 +639,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
const struct vo_driver video_out_x11 = {
|
||||
.description = "X11 ( XImage/Shm )",
|
||||
.name = "x11",
|
||||
.caps = VO_CAP_EVIL_OSD,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.options = (const struct m_option []){{0}},
|
||||
.preinit = preinit,
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "sub/draw_bmp.h"
|
||||
#include "video/csputils.h"
|
||||
#include "options/m_option.h"
|
||||
#include "input/input.h"
|
||||
#include "osdep/timer.h"
|
||||
|
||||
#define CK_METHOD_NONE 0 // no colorkey drawing
|
||||
@ -412,6 +413,8 @@ static void resize(struct vo *vo)
|
||||
xv_draw_colorkey(vo, &ctx->dst_rect);
|
||||
read_xv_csp(vo);
|
||||
|
||||
mp_input_set_mouse_transform(vo->input_ctx, &ctx->dst_rect, &ctx->src_rect);
|
||||
|
||||
vo->want_redraw = true;
|
||||
}
|
||||
|
||||
@ -843,16 +846,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
args->out_image = get_screenshot(vo);
|
||||
return true;
|
||||
}
|
||||
case VOCTRL_WINDOW_TO_OSD_COORDS: {
|
||||
float *c = data;
|
||||
struct mp_rect *src = &ctx->src_rect;
|
||||
struct mp_rect *dst = &ctx->dst_rect;
|
||||
c[0] = av_clipf(c[0], dst->x0, dst->x1) - dst->x0;
|
||||
c[1] = av_clipf(c[1], dst->y0, dst->y1) - dst->y0;
|
||||
c[0] = c[0] / (dst->x1 - dst->x0) * (src->x1 - src->x0) + src->x0;
|
||||
c[1] = c[1] / (dst->y1 - dst->y0) * (src->y1 - src->y0) + src->y0;
|
||||
return VO_TRUE;
|
||||
}
|
||||
}
|
||||
int events = 0;
|
||||
int r = vo_x11_control(vo, &events, request, data);
|
||||
@ -866,7 +859,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
const struct vo_driver video_out_xv = {
|
||||
.description = "X11/Xv",
|
||||
.name = "xv",
|
||||
.caps = VO_CAP_EVIL_OSD,
|
||||
.preinit = preinit,
|
||||
.query_format = query_format,
|
||||
.reconfig = reconfig,
|
||||
|
Loading…
Reference in New Issue
Block a user