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

Thomas Guillem thomas at gllm.fr
Fri Nov 25 18:40:07 CET 2016



On Fri, Nov 25, 2016, at 18:34, Rémi Denis-Courmont wrote:
> 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.

I don't understand your comment.
The vout window plugin can send window coordinates directly, the core
will transform it with all the needed info. I don't see what vout
plugins should care.

> 
> Nack
> -- 
> Rémi Denis-Courmont
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list