summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-27 21:33:11 +0200
committerwm4 <wm4@nowhere>2014-07-27 21:33:11 +0200
commit89391e7c949216d7edec461e9bb2cb6c787475c6 (patch)
tree0607c4609ffe505f810403585d54c8fa233e164f
parentbc6359313f55ef42e2e4737323844a224f17730b (diff)
downloadmpv-89391e7c949216d7edec461e9bb2cb6c787475c6.tar.bz2
mpv-89391e7c949216d7edec461e9bb2cb6c787475c6.tar.xz
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.
-rw-r--r--input/input.c29
-rw-r--r--input/input.h7
-rw-r--r--video/out/vo.c6
-rw-r--r--video/out/vo.h3
-rw-r--r--video/out/vo_wayland.c13
-rw-r--r--video/out/vo_x11.c15
-rw-r--r--video/out/vo_xv.c14
7 files changed, 47 insertions, 40 deletions
diff --git a/input/input.c b/input/input.c
index c035187126..97943e05b3 100644
--- a/input/input.c
+++ b/input/input.c
@@ -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;
diff --git a/input/input.h b/input/input.h
index 2dc7b4b366..2c572fa788 100644
--- a/input/input.h
+++ b/input/input.h
@@ -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);
diff --git a/video/out/vo.c b/video/out/vo.c
index f7dafa2735..db6a97eb26 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -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);
}
/**
diff --git a/video/out/vo.h b/video/out/vo.h
index 2dade4c9d1..cc1fd6c23a 100644
--- a/video/out/vo.h
+++ b/video/out/vo.h
@@ -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
diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c
index e0cf143fa0..2abb2b534f 100644
--- a/video/out/vo_wayland.c
+++ b/video/out/vo_wayland.c
@@ -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,
diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c
index 6cd2220c2b..f80bc0227f 100644
--- a/video/out/vo_x11.c
+++ b/video/out/vo_x11.c
@@ -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,
diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c
index e8f0fcd490..1ea16558ac 100644
--- a/video/out/vo_xv.c
+++ b/video/out/vo_xv.c
@@ -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,