[vlc-devel] [PATCH 2/2] core: window: handle mouse events

Rémi Denis-Courmont remi at remlab.net
Fri Nov 25 18:34:35 CET 2016


On November 25, 2016 6:39:35 PM GMT+02:00, Thomas Guillem <thomas at gllm.fr> wrote:
>Mouse events can now be caught by "vout window" modules in addition to
>"vout
>display" modules. Mouse events are propagated to the vout_thread_t via
>a new
>vout_control. That way, window mouse coordinates can be translated to
>video
>coordinates from ThreadControl (where it's safe to access vd->source
>and
>vd->cfg).
>
>Fix #9787
>---
>include/vlc_vout_window.h       | 88
>+++++++++++++++++++++++++++++++++++++++++
> src/video_output/control.h      |  4 ++
> src/video_output/opengl.c       |  1 +
> src/video_output/video_output.c | 56 ++++++++++++++++++++++++++
> src/video_output/vout_control.h |  5 +++
> src/video_output/window.c       |  7 ++++
> 6 files changed, 161 insertions(+)
>
>diff --git a/include/vlc_vout_window.h b/include/vlc_vout_window.h
>index c302e28..66f8347 100644
>--- a/include/vlc_vout_window.h
>+++ b/include/vlc_vout_window.h
>@@ -64,9 +64,33 @@ enum {
>     VOUT_WINDOW_SET_FULLSCREEN, /* int b_fullscreen */
> };
> 
>+/**
>+ * Window mouse event type for vout_window_mouse_event_t
>+ */
>+enum vout_window_mouse_event_type {
>+    VOUT_WINDOW_MOUSE_STATE,
>+    VOUT_WINDOW_MOUSE_MOVED,
>+    VOUT_WINDOW_MOUSE_PRESSED,
>+    VOUT_WINDOW_MOUSE_RELEASED,
>+    VOUT_WINDOW_MOUSE_DOUBLE_CLICK,
>+};
>+
>+/**
>+ * Window mouse event
>+ */
>+typedef struct vout_window_mouse_event_t
>+{
>+    enum vout_window_mouse_event_type type;
>+    int x;
>+    int y;
>+    int button_mask;
>+} vout_window_mouse_event_t;
>+
> enum {
>     VOUT_WINDOW_EVENT_RESIZED,  /* unsigned width, unsigned height */
>     VOUT_WINDOW_EVENT_CLOSED,   /* void */
>+
>+    VOUT_WINDOW_EVENT_MOUSE,    /* const vout_window_mouse_event_t *
>*/
> };
> 
> typedef struct vout_window_cfg_t {
>@@ -225,5 +249,69 @@ static inline void
>vout_window_ReportClose(vout_window_t *window)
>     vout_window_SendEvent(window, VOUT_WINDOW_EVENT_CLOSED);
> }
> 
>+/**
>+ * Send a full mouse state
>+ *
>+ * The mouse position must be expressed against window unit. You can
>use this
>+ * function of others vout_window_ReportMouse*() functions.
>+ */
>+static inline void vout_window_ReportMouseState(vout_window_t *window,
>+                                                int x, int y, int
>button_mask)
>+{
>+    const vout_window_mouse_event_t mouse = {
>+        VOUT_WINDOW_MOUSE_STATE, x, y, button_mask,
>+    };
>+    vout_window_SendEvent(window, VOUT_WINDOW_EVENT_MOUSE, &mouse);
>+}
>+
>+/**
>+ * Send a mouse movement
>+ *
>+ * The mouse position must be expressed against window unit.
>+ */
>+static inline void vout_window_ReportMouseMoved(vout_window_t *window,
>+                                                int x, int y)
>+{
>+    const vout_window_mouse_event_t mouse = {
>+        VOUT_WINDOW_MOUSE_MOVED, x, y, 0
>+    };
>+    vout_window_SendEvent(window, VOUT_WINDOW_EVENT_MOUSE, &mouse);
>+}
>+
>+/**
>+ * Send a mouse pressed event
>+ */
>+static inline void vout_window_ReportMousePressed(vout_window_t
>*window,
>+                                                  int button)
>+{
>+    const vout_window_mouse_event_t mouse = {
>+        VOUT_WINDOW_MOUSE_PRESSED, 0, 0, button,
>+    };
>+    vout_window_SendEvent(window, VOUT_WINDOW_EVENT_MOUSE, &mouse);
>+}
>+
>+/**
>+ * Send a mouse released event
>+ */
>+static inline void vout_window_ReportMouseReleased(vout_window_t
>*window,
>+                                                  int button)
>+{
>+    const vout_window_mouse_event_t mouse = {
>+        VOUT_WINDOW_MOUSE_RELEASED, 0, 0, button,
>+    };
>+    vout_window_SendEvent(window, VOUT_WINDOW_EVENT_MOUSE, &mouse);
>+}
>+
>+/**
>+ * Send a mouse double click event
>+ */
>+static inline void vout_window_ReportMouseDoubleClick(vout_window_t
>*window)
>+{
>+    const vout_window_mouse_event_t mouse = {
>+        VOUT_WINDOW_MOUSE_DOUBLE_CLICK, 0, 0, 0,
>+    };
>+    vout_window_SendEvent(window, VOUT_WINDOW_EVENT_MOUSE, &mouse);
>+}
>+
> /** @} */
> #endif /* VLC_VOUT_WINDOW_H */
>diff --git a/src/video_output/control.h b/src/video_output/control.h
>index 9fdfd85..6804742 100644
>--- a/src/video_output/control.h
>+++ b/src/video_output/control.h
>@@ -24,6 +24,8 @@
> #ifndef LIBVLC_VOUT_INTERNAL_CONTROL_H
> #define LIBVLC_VOUT_INTERNAL_CONTROL_H
> 
>+#include <vlc_vout_window.h>
>+
> /* */
> enum {
>     VOUT_CONTROL_INIT,
>@@ -51,6 +53,7 @@ enum {
> 
>     VOUT_CONTROL_FULLSCREEN,            /* bool */
>     VOUT_CONTROL_WINDOW_STATE,          /* unsigned */
>+    VOUT_CONTROL_WINDOW_MOUSE,          /* window_mouse */
>     VOUT_CONTROL_DISPLAY_FILLED,        /* bool */
>     VOUT_CONTROL_ZOOM,                  /* pair */
> 
>@@ -94,6 +97,7 @@ typedef struct {
>             unsigned width;
>             unsigned height;
>         } window;
>+        vout_window_mouse_event_t window_mouse;
>         const vout_configuration_t *cfg;
>         subpicture_t *subpicture;
>         vlc_viewpoint_t viewpoint;
>diff --git a/src/video_output/opengl.c b/src/video_output/opengl.c
>index 1a42253..a76f4d2 100644
>--- a/src/video_output/opengl.c
>+++ b/src/video_output/opengl.c
>@@ -115,6 +115,7 @@ static void vlc_gl_surface_Event(vout_window_t
>*wnd, int type, va_list args)
>                                         va_arg(args, unsigned));
>             break;
>         case VOUT_WINDOW_EVENT_CLOSED:
>+        case VOUT_WINDOW_EVENT_MOUSE:
>             /* TODO */
>             break;
>         default: vlc_assert_unreachable();
>diff --git a/src/video_output/video_output.c
>b/src/video_output/video_output.c
>index ef111ec..00036f7 100644
>--- a/src/video_output/video_output.c
>+++ b/src/video_output/video_output.c
>@@ -363,6 +363,17 @@ void vout_DisplayTitle(vout_thread_t *vout, const
>char *title)
>vout_control_PushString(&vout->p->control, VOUT_CONTROL_OSD_TITLE,
>title);
> }
> 
>+void vout_WindowMouseEvent(vout_thread_t *vout,
>+                           const vout_window_mouse_event_t *mouse)
>+{
>+    assert(mouse);
>+    vout_control_cmd_t cmd;
>+    vout_control_cmd_Init(&cmd, VOUT_CONTROL_WINDOW_MOUSE);
>+    cmd.u.window_mouse = *mouse;
>+
>+    vout_control_Push(&vout->p->control, &cmd);
>+}
>+
> void vout_PutSubpicture( vout_thread_t *vout, subpicture_t *subpic )
> {
>     vout_control_cmd_t cmd;
>@@ -1261,6 +1272,48 @@ static void
>ThreadChangeWindowState(vout_thread_t *vout, unsigned state)
> #endif
> }
> 
>+static void ThreadChangeWindowMouse(vout_thread_t *vout,
>+                                    const vout_window_mouse_event_t
>*mouse)
>+{
>+    vout_display_t *vd = vout->p->display.vd;
>+    switch (mouse->type)
>+    {
>+        case VOUT_WINDOW_MOUSE_STATE:
>+        case VOUT_WINDOW_MOUSE_MOVED:
>+        {
>+            vout_display_place_t place;
>+            vout_display_PlacePicture(&place, &vd->source, vd->cfg,
>false);
>+
>+            if (place.width <= 0 || place.height <= 0)
>+                return;
>+
>+            const int x = vd->source.i_x_offset +
>+                (int64_t)(mouse->x - place.x) *
>+                vd->source.i_visible_width / place.width;
>+            const int y = vd->source.i_y_offset +
>+                (int64_t)(mouse->y - place.y) *
>+                vd->source.i_visible_height/ place.height;
>+
>+            if (mouse->type == VOUT_WINDOW_MOUSE_STATE)
>+                vout_display_SendEventMouseState(vd, x, y,
>mouse->button_mask);
>+            else
>+                vout_display_SendEventMouseMoved(vd, x, y);
>+            break;
>+        }
>+        case VOUT_WINDOW_MOUSE_PRESSED:
>+            vout_display_SendEventMousePressed(vd,
>mouse->button_mask);
>+            break;
>+        case VOUT_WINDOW_MOUSE_RELEASED:
>+            vout_display_SendEventMouseReleased(vd,
>mouse->button_mask);
>+            break;
>+        case VOUT_WINDOW_MOUSE_DOUBLE_CLICK:
>+            vout_display_SendEventMouseDoubleClick(vd);
>+            break;
>+        default: vlc_assert_unreachable();
>+            break;
>+    }
>+}
>+
>static void ThreadChangeDisplayFilled(vout_thread_t *vout, bool
>is_filled)
> {
>     vout_SetDisplayFilled(vout->p->display.vd, is_filled);
>@@ -1551,6 +1604,9 @@ static int ThreadControl(vout_thread_t *vout,
>vout_control_cmd_t cmd)
>     case VOUT_CONTROL_WINDOW_STATE:
>         ThreadChangeWindowState(vout, cmd.u.integer);
>         break;
>+    case VOUT_CONTROL_WINDOW_MOUSE:
>+        ThreadChangeWindowMouse(vout, &cmd.u.window_mouse);
>+        break;
>     case VOUT_CONTROL_DISPLAY_FILLED:
>         ThreadChangeDisplayFilled(vout, cmd.u.boolean);
>         break;
>diff --git a/src/video_output/vout_control.h
>b/src/video_output/vout_control.h
>index 0be3313..e50c096 100644
>--- a/src/video_output/vout_control.h
>+++ b/src/video_output/vout_control.h
>@@ -25,6 +25,8 @@
> #ifndef LIBVLC_VOUT_CONTROL_H
> #define LIBVLC_VOUT_CONTROL_H 1
> 
>+typedef struct vout_window_mouse_event_t vout_window_mouse_event_t;
>+
> /**
>  * This function will (un)pause the display of pictures.
>  * It is thread safe
>@@ -69,6 +71,9 @@ void vout_NextPicture( vout_thread_t *p_vout, mtime_t
>*pi_duration );
>  */
>void vout_DisplayTitle( vout_thread_t *p_vout, const char *psz_title );
> 
>+void vout_WindowMouseEvent( vout_thread_t *p_vout,
>+                            const vout_window_mouse_event_t *mouse );
>+
> /**
>* This function will return true if no more pictures are to be
>displayed.
>  */
>diff --git a/src/video_output/window.c b/src/video_output/window.c
>index 11ed099..76d7e5a 100644
>--- a/src/video_output/window.c
>+++ b/src/video_output/window.c
>@@ -164,6 +164,13 @@ static void
>vout_display_window_Event(vout_window_t *window, int type,
>         case VOUT_WINDOW_EVENT_CLOSED:
>             vout_display_window_CloseNotify(window);
>             break;
>+        case VOUT_WINDOW_EVENT_MOUSE:
>+        {
>+            vout_thread_t *vout = (vout_thread_t *)window->obj.parent;
>+            vout_WindowMouseEvent(vout,
>+                                  va_arg(args, const
>vout_window_mouse_event_t*));
>+            break;
>+        }
>         default: vlc_assert_unreachable();
>     }
> }
>-- 
>2.9.3
>
>_______________________________________________
>vlc-devel mailing list
>To unsubscribe or modify your subscription options:
>https://mailman.videolan.org/listinfo/vlc-devel

I don't see why the vout plugins have to care. Core has all the neede info.

Nack
-- 
Rémi Denis-Courmont


More information about the vlc-devel mailing list