[vlc-commits] [Git][videolan/vlc][master] 16 commits: vout: protect filter chain creation/destruction

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Tue May 17 19:43:49 UTC 2022



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
2386f6bc by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
vout: protect filter chain creation/destruction

Windows can send input events even if there is no display, so the
filter chains may need to be accessed even then. This protects the
creation and destruction of the chains with the existing filter lock,
providing memory safety.

- - - - -
6af828f1 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
vout: factor out mouse filtering

- - - - -
6fc88446 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
display: typedef vout_display_cfg_t::display

No functional changes.

- - - - -
cc4456fd by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
vout: gather video placement properties

This puts all the video size and placement properties back together as
vout_display_cfg_t originally was before other parameters were added.

No functional changes.

- - - - -
cdc53878 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
display: update vout_display_GetDefaultDisplaySize() prototype

Take only a struct vout_display_size rather than a full
struct vout_display_cfg_t. No functional changes.

- - - - -
c58018e4 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
display: update vout_display_PlacePicture() prototype

Take only a struct vout_display_size rather than a full
struct vout_display_cfg_t. No functional changes.

- - - - -
48a90e99 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
display: update vout_display_TranslateCoordiantes() prototype

Take only a struct vout_display_size rather than a full
struct vout_display_cfg_t. No functional changes.

- - - - -
08b147be by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
window: update vout_display_SizeWindow() prototype

Take only a struct vout_display_size rather than a full
struct vout_display_cfg_t. No functional changes.

- - - - -
5e61db7c by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
window: appropriate resize code

No functional changes.

- - - - -
6f7e056e by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
window: track display and video sizes

- - - - -
dfcdacd1 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
window: translate mouse coordinates

This takes mouse coordinates translation out of the video output and
into the video window code, getting rid of one display lock dependency.

- - - - -
5cb39aeb by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
display: remove vout_display_TranslateMouseState()

This is no longer used.

- - - - -
3ed5be7b by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
window: gather mouse state in a substructure

No functional changes.

- - - - -
851efba5 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
window: track mouse callback

This gets set explicitly when the video output is started, which always
results in the window being (re)enabled. Conversely, this gets
implicitly unset when the video output is stopped, which always results
in the window being disabled.

- - - - -
6bfaa528 by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
window: dispatch mouse events

- - - - -
a2e0adec by Rémi Denis-Courmont at 2022-05-17T19:14:06+00:00
vout: remove write-only mouse_event

- - - - -


20 changed files:

- include/vlc_vout_display.h
- modules/hw/mmal/vout.c
- modules/hw/vdpau/display.c
- modules/video_output/caopengllayer.m
- modules/video_output/drm/display.c
- modules/video_output/kva.c
- modules/video_output/libplacebo/display.c
- modules/video_output/macosx.m
- modules/video_output/opengl/display.c
- modules/video_output/splitter.c
- modules/video_output/wayland/shm.c
- modules/video_output/win32/common.c
- modules/video_output/win32/glwin32.c
- modules/video_output/xcb/render.c
- modules/video_output/xcb/x11.c
- src/video_output/display.c
- src/video_output/video_output.c
- src/video_output/video_window.c
- src/video_output/video_window.h
- src/video_output/vout_internal.h


Changes:

=====================================
include/vlc_vout_display.h
=====================================
@@ -77,12 +77,25 @@ typedef struct vlc_video_align {
 } vlc_video_align_t;
 /** @} */
 
+/**
+ * Display placement and zoom configuration.
+ */
+struct vout_display_placement {
+    unsigned width; /**< Requested display pixel width (0 by default). */
+    unsigned height; /**< Requested display pixel height (0 by default). */
+    vlc_rational_t sar; /**< Requested sample aspect ratio */
+
+    vlc_video_align_t align; /**< Alignment within the window */
+    bool autoscale; /**< Automatic scaling/fitting flag */
+    vlc_rational_t zoom; /**< Zoom ratio (if autoscale is disabled) */
+};
+
 /**
  * User configuration for a video output display (\ref vout_display_t)
  *
  * This primarily controls the size of the display area within the video
  * window, as follows:
- * - If \ref vout_display_cfg::is_display_filled "is_display_filled" is set,
+ * - If \ref vout_display_cfg::display::autoscale is set,
  *   the video size is fitted to the display size.
  * - If \ref vout_display_cfg::window "window" size is valid, the video size
  *   is set to the window size,
@@ -91,23 +104,7 @@ typedef struct vlc_video_align {
  */
 typedef struct vout_display_cfg {
     struct vlc_window *window; /**< Window */
-
-    /** Display properties */
-    struct {
-        unsigned width; /**< Requested display pixel width (0 by default). */
-        unsigned height; /**< Requested display pixel height (0 by default). */
-        vlc_rational_t sar; /**< Requested sample aspect ratio */
-    } display;
-
-    /** Alignment of the video within the window */
-    vlc_video_align_t align;
-
-    /** Automatic scaling/fitting flag */
-    bool is_display_filled;
-
-    /** Zoom ratio */
-    vlc_rational_t zoom;
-
+    struct vout_display_placement display; /**< Display placement properties */
     vlc_viewpoint_t viewpoint;
 } vout_display_cfg_t;
 
@@ -457,8 +454,10 @@ static inline bool vout_display_cfg_IsWindowed(const vout_display_cfg_t *cfg)
  *
  * This assumes that the picture is already cropped.
  */
-VLC_API void vout_display_GetDefaultDisplaySize(unsigned *width, unsigned *height, const video_format_t *source, const vout_display_cfg_t *);
-
+VLC_API
+void vout_display_GetDefaultDisplaySize(unsigned *width, unsigned *height,
+                                        const video_format_t *source,
+                                        const struct vout_display_placement *);
 
 /**
  * Video placement.
@@ -495,7 +494,10 @@ static inline bool vout_display_PlaceEquals(const vout_display_place_t *p1,
  * \param source Video source format
  * \param cfg Display configuration
  */
-VLC_API void vout_display_PlacePicture(vout_display_place_t *place, const video_format_t *source, const vout_display_cfg_t *cfg);
+VLC_API
+void vout_display_PlacePicture(vout_display_place_t *restrict place,
+                               const video_format_t *restrict source,
+                               const struct vout_display_placement *cfg);
 
 /**
  * Translates coordinates.
@@ -506,21 +508,11 @@ VLC_API void vout_display_PlacePicture(vout_display_place_t *place, const video_
  * \param x pointer to abscissa to be translated
  * \param y pointer to ordinate to be translated
  * \param fmt video format
- * \param cfg display configuration
+ * \param dp display configuration
  */
 void vout_display_TranslateCoordinates(int *x, int *y,
                                        const video_format_t *fmt,
-                                       const vout_display_cfg_t *cfg);
-
-/**
- * Translates mouse state.
- *
- * This translates the mouse (pointer) state from window coordinates to
- * video coordinates.
- * @note @c video and @c window pointers may alias.
- */
-void vout_display_TranslateMouseState(vout_display_t *vd, vlc_mouse_t *video,
-                                      const vlc_mouse_t *window);
+                                       const struct vout_display_placement *dp);
 
 /** @} */
 #endif /* VLC_VOUT_DISPLAY_H */


=====================================
modules/hw/mmal/vout.c
=====================================
@@ -515,18 +515,17 @@ place_dest(vout_display_t *vd, const video_format_t * fmt)
 {
     vout_display_sys_t * const sys = vd->sys;
     // Ignore what VLC thinks might be going on with display size
-    vout_display_cfg_t tcfg = *vd->cfg;
+    struct vout_display_placement dp = vd->cfg->display;
     vout_display_place_t place;
-    tcfg.display.width = sys->display_width;
-    tcfg.display.height = sys->display_height;
-    tcfg.is_display_filled = true;
-    vout_display_PlacePicture(&place, fmt, &tcfg);
+
+    dp.width = sys->display_width;
+    dp.height = sys->display_height;
+    dp.autoscale = true;
+    vout_display_PlacePicture(&place, fmt, &dp);
 
     sys->dest_rect = place_to_mmal_rect(place);
 }
 
-
-
 static int configure_display(vout_display_t *vd, const video_format_t *fmt)
 {
     vout_display_sys_t * const sys = vd->sys;


=====================================
modules/hw/vdpau/display.c
=====================================
@@ -230,7 +230,7 @@ static int ResetPictures(vout_display_t *vd, video_format_t *fmt)
     vout_display_place_t place;
 
     msg_Dbg(vd, "resetting pictures");
-    vout_display_PlacePicture(&place, src, vd->cfg);
+    vout_display_PlacePicture(&place, src, &vd->cfg->display);
 
     fmt->i_width = src->i_width * place.width / src->i_visible_width;
     fmt->i_height = src->i_height * place.height / src->i_visible_height;
@@ -259,7 +259,7 @@ static int Control(vout_display_t *vd, int query)
     {
         vout_display_place_t place;
 
-        vout_display_PlacePicture(&place, vd->source, vd->cfg);
+        vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
         if (place.width  != vd->fmt->i_visible_width
          || place.height != vd->fmt->i_visible_height)
             return VLC_EGENERIC;
@@ -395,7 +395,7 @@ static int Open(vout_display_t *vd,
         };
         vout_display_place_t place;
 
-        vout_display_PlacePicture(&place, vd->source, vd->cfg);
+        vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
         sys->window = xcb_generate_id(sys->conn);
 
         xcb_void_cookie_t c =


=====================================
modules/video_output/caopengllayer.m
=====================================
@@ -347,10 +347,10 @@ static int Open (vout_display_t *vd,
         dispatch_sync(dispatch_get_main_queue(), ^{
             // Reverse vertical alignment as the GL tex are Y inverted
            sys->cfg = *vd->cfg;
-           if (sys->cfg.align.vertical == VLC_VIDEO_ALIGN_TOP)
-               sys->cfg.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
-           else if (sys->cfg.align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
-               sys->cfg.align.vertical = VLC_VIDEO_ALIGN_TOP;
+           if (sys->cfg.display.align.vertical == VLC_VIDEO_ALIGN_TOP)
+               sys->cfg.display.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
+           else if (sys->cfg.display.align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
+               sys->cfg.display.align.vertical = VLC_VIDEO_ALIGN_TOP;
 
             // Create video view
             sys->videoView = [[VLCVideoLayerView alloc] initWithVoutDisplay:vd];
@@ -370,7 +370,7 @@ static int Open (vout_display_t *vd,
                 sys->videoLayer = nil;
             }
 
-            vout_display_PlacePicture(&sys->place, vd->source, &sys->cfg);
+            vout_display_PlacePicture(&sys->place, vd->source, &sys->cfg.display);
         });
 
         if (sys->videoView == nil) {
@@ -502,13 +502,13 @@ static int Control (vout_display_t *vd, int query)
                 cfg.display.height = sys->cfg.display.height;
 
                 // Reverse vertical alignment as the GL tex are Y inverted
-                if (cfg.align.vertical == VLC_VIDEO_ALIGN_TOP)
-                    cfg.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
-                else if (cfg.align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
-                    cfg.align.vertical = VLC_VIDEO_ALIGN_TOP;
+                if (cfg.display.align.vertical == VLC_VIDEO_ALIGN_TOP)
+                    cfg.display.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
+                else if (cfg.display.align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
+                    cfg.display.align.vertical = VLC_VIDEO_ALIGN_TOP;
                 sys->cfg = cfg;
 
-                vout_display_PlacePicture(&sys->place, vd->source, &cfg);
+                vout_display_PlacePicture(&sys->place, vd->source, &cfg.display);
             }
 
             // Note!


=====================================
modules/video_output/drm/display.c
=====================================
@@ -100,7 +100,7 @@ static void Display(vout_display_t *vd, picture_t *picture)
     picture_t *pic = sys->buffers[sys->front_buf];
     vout_display_place_t place;
 
-    vout_display_PlacePicture(&place, vd->fmt, vd->cfg);
+    vout_display_PlacePicture(&place, vd->fmt, &vd->cfg->display);
 
     struct drm_mode_set_plane sp = {
         .plane_id = sys->plane_id,


=====================================
modules/video_output/kva.c
=====================================
@@ -409,7 +409,7 @@ static int Control( vout_display_t *vd, int query )
     case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
     {
         vout_display_place_t place;
-        vout_display_PlacePicture(&place, vd->source, vd->cfg);
+        vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
 
         sys->kvas.ulAspectWidth  = place.width;
         sys->kvas.ulAspectHeight = place.height;
@@ -893,7 +893,7 @@ static MRESULT EXPENTRY WndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
             i_movie_height = movie_rect.yTop - movie_rect.yBottom;
 
             vout_display_place_t place;
-            vout_display_PlacePicture(&place, vd->source, vd->cfg);
+            vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
 
             int x = ( i_mouse_x - movie_rect.xLeft ) *
                     place.width / i_movie_width + place.x;


=====================================
modules/video_output/libplacebo/display.c
=====================================
@@ -282,17 +282,22 @@ static void PictureRender(vout_display_t *vd, picture_t *pic,
 
     // Set the target crop dynamically based on the swapchain flip state
     vout_display_place_t place;
-    vout_display_cfg_t cfg = *vd->cfg;
-    cfg.display.width = frame.fbo->params.w;
-    cfg.display.height = frame.fbo->params.h;
+    struct vout_display_placement dp = vd->cfg->display;
+    dp.width = frame.fbo->params.w;
+    dp.height = frame.fbo->params.h;
     if (need_vflip) {
-        switch (cfg.align.vertical) {
-        case VLC_VIDEO_ALIGN_TOP: cfg.align.vertical = VLC_VIDEO_ALIGN_BOTTOM; break;
-        case VLC_VIDEO_ALIGN_BOTTOM: cfg.align.vertical = VLC_VIDEO_ALIGN_TOP; break;
-        default: break;
+        switch (dp.align.vertical) {
+        case VLC_VIDEO_ALIGN_TOP:
+            dp.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
+            break;
+        case VLC_VIDEO_ALIGN_BOTTOM:
+            dp.align.vertical = VLC_VIDEO_ALIGN_TOP;
+            break;
+        default:
+            break;
         }
     }
-    vout_display_PlacePicture(&place, vd->fmt, &cfg);
+    vout_display_PlacePicture(&place, vd->fmt, &dp);
     if (need_vflip) {
         place.y = frame.fbo->params.h - place.y;
         place.height = -place.height;


=====================================
modules/video_output/macosx.m
=====================================
@@ -331,7 +331,7 @@ static void UpdatePlace (vout_display_t *vd, const vout_display_cfg_t *cfg)
     vout_display_sys_t *sys = vd->sys;
     vout_display_place_t place;
     /* We never receive resize from the core, so provide the size ourselves */
-    vout_display_PlacePicture(&place, vd->source, cfg);
+    vout_display_PlacePicture(&place, vd->source, &cfg->display);
     sys->place = place;
 }
 
@@ -358,10 +358,10 @@ static int Control (vout_display_t *vd, int query)
                     vout_display_cfg_t cfg;
                     cfg = *vd->cfg;
                     /* Reverse vertical alignment as the GL tex are Y inverted */
-                    if (cfg.align.vertical == VLC_VIDEO_ALIGN_TOP)
-                        cfg.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
-                    else if (cfg.align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
-                        cfg.align.vertical = VLC_VIDEO_ALIGN_TOP;
+                    if (cfg.display.align.vertical == VLC_VIDEO_ALIGN_TOP)
+                        cfg.display.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
+                    else if (cfg.display.align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
+                        cfg.display.align.vertical = VLC_VIDEO_ALIGN_TOP;
                     cfg.display.width = sys->cfg.display.width;
                     cfg.display.height = sys->cfg.display.height;
                     sys->cfg = cfg;


=====================================
modules/video_output/opengl/display.c
=====================================
@@ -104,13 +104,13 @@ static const struct vlc_display_operations ops = {
 };
 
 static void
-FlipVerticalAlign(vout_display_cfg_t *cfg)
+FlipVerticalAlign(struct vout_display_placement *dp)
 {
     /* Reverse vertical alignment as the GL tex are Y inverted */
-    if (cfg->align.vertical == VLC_VIDEO_ALIGN_TOP)
-        cfg->align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
-    else if (cfg->align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
-        cfg->align.vertical = VLC_VIDEO_ALIGN_TOP;
+    if (dp->align.vertical == VLC_VIDEO_ALIGN_TOP)
+        dp->align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
+    else if (dp->align.vertical == VLC_VIDEO_ALIGN_BOTTOM)
+        dp->align.vertical = VLC_VIDEO_ALIGN_TOP;
 }
 
 /**
@@ -164,9 +164,9 @@ static int Open(vout_display_t *vd,
     if (sys->vt.Flush == NULL)
         goto error;
 
-    vout_display_cfg_t flipped_cfg = *vd->cfg;
-    FlipVerticalAlign(&flipped_cfg);
-    vout_display_PlacePicture(&sys->place, vd->source, &flipped_cfg);
+    struct vout_display_placement flipped_dp = vd->cfg->display;
+    FlipVerticalAlign(&flipped_dp);
+    vout_display_PlacePicture(&sys->place, vd->source, &flipped_dp);
     sys->place_changed = true;
     vlc_gl_Resize (sys->gl, vd->cfg->display.width, vd->cfg->display.height);
 
@@ -257,24 +257,24 @@ static int Control (vout_display_t *vd, int query)
       case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
       case VOUT_DISPLAY_CHANGE_ZOOM:
       {
-        vout_display_cfg_t cfg = *vd->cfg;
+        struct vout_display_placement dp = vd->cfg->display;
 
-        FlipVerticalAlign(&cfg);
+        FlipVerticalAlign(&dp);
 
-        vout_display_PlacePicture(&sys->place, vd->source, &cfg);
+        vout_display_PlacePicture(&sys->place, vd->source, &dp);
         sys->place_changed = true;
-        vlc_gl_Resize (sys->gl, cfg.display.width, cfg.display.height);
+        vlc_gl_Resize (sys->gl, dp.width, dp.height);
         return VLC_SUCCESS;
       }
 
       case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
       case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
       {
-        vout_display_cfg_t cfg = *vd->cfg;
+        struct vout_display_placement dp = vd->cfg->display;
 
-        FlipVerticalAlign(&cfg);
+        FlipVerticalAlign(&dp);
 
-        vout_display_PlacePicture(&sys->place, vd->source, &cfg);
+        vout_display_PlacePicture(&sys->place, vd->source, &dp);
         sys->place_changed = true;
         return VLC_SUCCESS;
       }


=====================================
modules/video_output/splitter.c
=====================================
@@ -214,7 +214,7 @@ static vlc_window_t *video_splitter_CreateWindow(vlc_object_t *obj,
     };
 
     vout_display_GetDefaultDisplaySize(&cfg.width, &cfg.height, source,
-                                       vdcfg);
+                                       &vdcfg->display);
 
     vlc_window_t *window = vlc_window_New(obj, NULL, &owner, &cfg);
     if (window != NULL) {
@@ -278,10 +278,14 @@ static int vlc_vidsplit_Open(vout_display_t *vd,
     for (int i = 0; i < splitter->i_output; i++) {
         const video_splitter_output_t *output = &splitter->p_output[i];
         vout_display_cfg_t vdcfg = {
-            .display = { 0, 0, { 1, 1 } },
-            .align = { 0, 0 } /* TODO */,
-            .is_display_filled = true,
-            .zoom = { 1, 1 },
+            .display = {
+                .width = 0,
+                .height = 0,
+                .sar = { 1, 1 },
+                .align = { 0, 0 } /* TODO */,
+                .autoscale = true,
+                .zoom = { 1, 1 },
+            },
         };
         const char *modname = output->psz_module;
         struct vlc_vidsplit_part *part = &sys->parts[i];


=====================================
modules/video_output/wayland/shm.c
=====================================
@@ -156,7 +156,7 @@ static int ResetPictures(vout_display_t *vd, video_format_t *fmt)
     vout_display_sys_t *sys = vd->sys;
     assert(sys->viewport == NULL);
 
-    vout_display_PlacePicture(&place, vd->source, vd->cfg);
+    vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
     video_format_ApplyRotation(&src, vd->source);
 
     fmt->i_width  = src.i_width * place.width
@@ -190,7 +190,8 @@ static int Control(vout_display_t *vd, int query)
                 vout_display_place_t place;
 
                 video_format_ApplyRotation(&fmt, vd->source);
-                vout_display_PlacePicture(&place, vd->source, vd->cfg);
+                vout_display_PlacePicture(&place, vd->source,
+                                          &vd->cfg->display);
 
                 wp_viewport_set_source(sys->viewport,
                                 wl_fixed_from_int(fmt.i_x_offset),


=====================================
modules/video_output/win32/common.c
=====================================
@@ -97,7 +97,7 @@ void CommonPlacePicture(vout_display_t *vd, display_win32_area_t *area)
 {
     /* Update the window position and size */
     vout_display_place_t before_place = area->place;
-    vout_display_PlacePicture(&area->place, vd->source, vd->cfg);
+    vout_display_PlacePicture(&area->place, vd->source, &vd->cfg->display);
 
     /* Signal the change in size/position */
     if (!vout_display_PlaceEquals(&before_place, &area->place))


=====================================
modules/video_output/win32/glwin32.c
=====================================
@@ -216,7 +216,7 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
         return;
     if (sys->area.place_changed)
     {
-        vout_display_cfg_t place_cfg = *vd->cfg;
+        struct vout_display_placement place_cfg = vd->cfg->display;
         vout_display_place_t place;
 
         /* Reverse vertical alignment as the GL tex are Y inverted */


=====================================
modules/video_output/xcb/render.c
=====================================
@@ -281,7 +281,7 @@ static void CreateBuffers(vout_display_t *vd)
                               sys->format.argb, 0, NULL);
 
     vout_display_place_t *place = &sys->place;
-    vout_display_PlacePicture(place, fmt, vd->cfg);
+    vout_display_PlacePicture(place, fmt, &vd->cfg->display);
 
     /* Homogeneous coordinates transform from destination(place)
      * to source(fmt) */


=====================================
modules/video_output/xcb/x11.c
=====================================
@@ -217,7 +217,7 @@ static int Control(vout_display_t *vd, int query)
         vout_display_place_t *place = &sys->place;
         int ret = VLC_SUCCESS;
 
-        vout_display_PlacePicture(place, vd->source, vd->cfg);
+        vout_display_PlacePicture(place, vd->source, &vd->cfg->display);
 
         if (place->width  != sys->fmt.i_visible_width
          || place->height != sys->fmt.i_visible_height)
@@ -376,7 +376,7 @@ static int Open (vout_display_t *vd,
     };
     vout_display_place_t *place = &sys->place;
 
-    vout_display_PlacePicture(place, vd->source, vd->cfg);
+    vout_display_PlacePicture(place, vd->source, &vd->cfg->display);
     sys->window = xcb_generate_id (conn);
     sys->gc = xcb_generate_id (conn);
     xcb_create_window(conn, sys->depth, sys->window,


=====================================
src/video_output/display.c
=====================================
@@ -73,19 +73,19 @@ static int vout_display_Control(vout_display_t *vd, int query)
 /* */
 void vout_display_GetDefaultDisplaySize(unsigned *width, unsigned *height,
                                         const video_format_t *source,
-                                        const vout_display_cfg_t *cfg)
+                                        const struct vout_display_placement *dp)
 {
     /* Use the original video size */
     if (source->i_sar_num >= source->i_sar_den) {
-        *width  = (int64_t)source->i_visible_width * source->i_sar_num * cfg->display.sar.den / source->i_sar_den / cfg->display.sar.num;
+        *width  = (int64_t)source->i_visible_width * source->i_sar_num * dp->sar.den / source->i_sar_den / dp->sar.num;
         *height = source->i_visible_height;
     } else {
         *width  = source->i_visible_width;
-        *height = (int64_t)source->i_visible_height * source->i_sar_den * cfg->display.sar.num / source->i_sar_num / cfg->display.sar.den;
+        *height = (int64_t)source->i_visible_height * source->i_sar_den * dp->sar.num / source->i_sar_num / dp->sar.den;
     }
 
-    *width  = *width  * cfg->zoom.num / cfg->zoom.den;
-    *height = *height * cfg->zoom.num / cfg->zoom.den;
+    *width  = *width  * dp->zoom.num / dp->zoom.den;
+    *height = *height * dp->zoom.num / dp->zoom.den;
 
     if (ORIENT_IS_SWAP(source->orientation)) {
         /* Apply the source orientation only if the dimensions are initialized
@@ -97,12 +97,12 @@ void vout_display_GetDefaultDisplaySize(unsigned *width, unsigned *height,
 }
 
 /* */
-void vout_display_PlacePicture(vout_display_place_t *place,
-                               const video_format_t *source,
-                               const vout_display_cfg_t *cfg)
+void vout_display_PlacePicture(vout_display_place_t *restrict place,
+                               const video_format_t *restrict source,
+                               const struct vout_display_placement *restrict dp)
 {
     memset(place, 0, sizeof(*place));
-    if (cfg->display.width == 0 || cfg->display.height == 0)
+    if (dp->width == 0 || dp->height == 0)
         return;
 
     /* */
@@ -113,23 +113,23 @@ void vout_display_PlacePicture(vout_display_place_t *place,
     video_format_ApplyRotation(&source_rot, source);
     source = &source_rot;
 
-    if (cfg->is_display_filled) {
-        display_width  = cfg->display.width;
-        display_height = cfg->display.height;
+    if (dp->autoscale) {
+        display_width  = dp->width;
+        display_height = dp->height;
     } else
         vout_display_GetDefaultDisplaySize(&display_width, &display_height,
-                                           source, cfg);
+                                           source, dp);
 
     const unsigned width  = source->i_visible_width;
     const unsigned height = source->i_visible_height;
     /* Compute the height if we use the width to fill up display_width */
-    const int64_t scaled_height = (int64_t)height * display_width  * cfg->display.sar.num * source->i_sar_den / (width  * source->i_sar_num * cfg->display.sar.den);
+    const int64_t scaled_height = (int64_t)height * display_width  * dp->sar.num * source->i_sar_den / (width  * source->i_sar_num * dp->sar.den);
     /* And the same but switching width/height */
-    const int64_t scaled_width  = (int64_t)width  * display_height * cfg->display.sar.den * source->i_sar_num / (height * source->i_sar_den * cfg->display.sar.num);
+    const int64_t scaled_width  = (int64_t)width  * display_height * dp->sar.den * source->i_sar_num / (height * source->i_sar_den * dp->sar.num);
 
     if (source->projection_mode == PROJECTION_MODE_RECTANGULAR) {
         /* We keep the solution that avoid filling outside the display */
-        if (scaled_width <= cfg->display.width) {
+        if (scaled_width <= dp->width) {
             place->width  = scaled_width;
             place->height = display_height;
         } else {
@@ -144,27 +144,27 @@ void vout_display_PlacePicture(vout_display_place_t *place,
     }
 
     /*  Compute position */
-    switch (cfg->align.horizontal) {
+    switch (dp->align.horizontal) {
     case VLC_VIDEO_ALIGN_LEFT:
         place->x = 0;
         break;
     case VLC_VIDEO_ALIGN_RIGHT:
-        place->x = cfg->display.width - place->width;
+        place->x = dp->width - place->width;
         break;
     default:
-        place->x = ((int)cfg->display.width - (int)place->width) / 2;
+        place->x = ((int)dp->width - (int)place->width) / 2;
         break;
     }
 
-    switch (cfg->align.vertical) {
+    switch (dp->align.vertical) {
     case VLC_VIDEO_ALIGN_TOP:
         place->y = 0;
         break;
     case VLC_VIDEO_ALIGN_BOTTOM:
-        place->y = cfg->display.height - place->height;
+        place->y = dp->height - place->height;
         break;
     default:
-        place->y = ((int)cfg->display.height - (int)place->height) / 2;
+        place->y = ((int)dp->height - (int)place->height) / 2;
         break;
     }
 }
@@ -172,11 +172,11 @@ void vout_display_PlacePicture(vout_display_place_t *place,
 /** Translates window coordinates to video coordinates */
 void vout_display_TranslateCoordinates(int *restrict xp, int *restrict yp,
                                        const video_format_t *restrict source,
-                                       const vout_display_cfg_t *restrict cfg)
+                                       const struct vout_display_placement *restrict dp)
 {
     vout_display_place_t place;
 
-    vout_display_PlacePicture(&place, source, cfg);
+    vout_display_PlacePicture(&place, source, dp);
 
     if (place.width <= 0 || place.height <= 0)
         return;
@@ -229,14 +229,6 @@ void vout_display_TranslateCoordinates(int *restrict xp, int *restrict yp,
     *yp = y;
 }
 
-void vout_display_TranslateMouseState(vout_display_t *vd, vlc_mouse_t *video,
-                                      const vlc_mouse_t *window)
-{
-    *video = *window;
-    vout_display_TranslateCoordinates(&video->i_x, &video->i_y, vd->source,
-                                      vd->cfg);
-}
-
 typedef struct {
     vout_display_t  display;
 
@@ -539,10 +531,10 @@ void vout_SetDisplayFilled(vout_display_t *vd, bool is_filled)
 {
     vout_display_priv_t *osys = container_of(vd, vout_display_priv_t, display);
 
-    if (is_filled == osys->cfg.is_display_filled)
+    if (is_filled == osys->cfg.display.autoscale)
         return; /* nothing to do */
 
-    osys->cfg.is_display_filled = is_filled;
+    osys->cfg.display.autoscale = is_filled;
     if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_DISPLAY_FILLED))
         vout_display_Reset(vd);
 }
@@ -551,12 +543,12 @@ void vout_SetDisplayZoom(vout_display_t *vd, unsigned num, unsigned den)
 {
     vout_display_priv_t *osys = container_of(vd, vout_display_priv_t, display);
 
-    if (!osys->cfg.is_display_filled
-     && osys->cfg.zoom.num == num && osys->cfg.zoom.den == den)
+    if (!osys->cfg.display.autoscale
+     && osys->cfg.display.zoom.num == num && osys->cfg.display.zoom.den == den)
         return; /* nothing to do */
 
-    osys->cfg.zoom.num = num;
-    osys->cfg.zoom.den = den;
+    osys->cfg.display.zoom.num = num;
+    osys->cfg.display.zoom.den = den;
     if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_ZOOM))
         vout_display_Reset(vd);
 }
@@ -634,7 +626,7 @@ vout_display_t *vout_display_New(vlc_object_t *parent,
         msg_Warn(parent, "window size missing");
         vout_display_GetDefaultDisplaySize(&osys->cfg.display.width,
                                            &osys->cfg.display.height,
-                                           source, cfg);
+                                           source, &cfg->display);
     }
 
     osys->pool = NULL;


=====================================
src/video_output/video_output.c
=====================================
@@ -133,8 +133,6 @@ typedef struct vout_thread_sys_t
 
     /* */
     vlc_mouse_t     mouse;
-    vlc_mouse_event mouse_event;
-    void            *mouse_opaque;
 
     /* Video output window */
     bool            window_enabled;
@@ -225,16 +223,14 @@ static bool VideoFormatIsCropArEqual(video_format_t *dst,
 static void vout_UpdateWindowSizeLocked(vout_thread_sys_t *vout)
 {
     vout_thread_sys_t *sys = vout;
-    unsigned width, height;
 
     if (unlikely(sys->original.i_chroma == 0))
         return; /* not started yet, postpone size computaton */
 
     vlc_mutex_assert(&sys->window_lock);
-    vout_display_SizeWindow(&width, &height, &sys->original, &sys->source.dar,
-                            &sys->source.crop, &sys->display_cfg);
-    msg_Dbg(&vout->obj, "requested window size: %ux%u", width, height);
-    vlc_window_SetSize(sys->display_cfg.window, width, height);
+    vout_display_ResizeWindow(sys->display_cfg.window, &sys->original,
+                              &sys->source.dar, &sys->source.crop,
+                              &sys->display_cfg.display);
 }
 
 /* */
@@ -269,25 +265,10 @@ void vout_DisplayTitle(vout_thread_t *vout, const char *title)
                  VLC_TICK_FROM_MS(sys->title.timeout), title);
 }
 
-void vout_MouseState(vout_thread_t *vout, const vlc_mouse_t *mouse)
+void vout_FilterMouse(vout_thread_t *vout, vlc_mouse_t *mouse)
 {
     vout_thread_sys_t *sys = VOUT_THREAD_TO_SYS(vout);
-    vlc_mouse_t video_mouse, tmp[2];
-    const vlc_mouse_t *m = &video_mouse;
-    bool has_display;
-
-    assert(!sys->dummy);
-    assert(mouse);
-
-    /* Translate window coordinates to video coordinates */
-    vlc_mutex_lock(&sys->display_lock);
-    has_display = sys->display != NULL;
-    if (has_display)
-        vout_display_TranslateMouseState(sys->display, &video_mouse, mouse);
-    vlc_mutex_unlock(&sys->display_lock);
-
-    if (!has_display)
-        return;
+    vlc_mouse_t tmp[2], *m = mouse;
 
     /* Pass mouse events through the filter chains. */
     vlc_mutex_lock(&sys->filter.lock);
@@ -302,23 +283,8 @@ void vout_MouseState(vout_thread_t *vout, const vlc_mouse_t *mouse)
     }
     vlc_mutex_unlock(&sys->filter.lock);
 
-    /* Check if the mouse state actually changed and emit events. */
-    /* NOTE: sys->mouse is only used here, so no need to lock. */
-
-    if (vlc_mouse_HasMoved(&sys->mouse, m))
-        var_SetCoords(vout, "mouse-moved", m->i_x, m->i_y);
-    if (vlc_mouse_HasButton(&sys->mouse, m))
-        var_SetInteger(vout, "mouse-button-down", m->i_pressed);
-    if (m->b_double_click)
-        var_ToggleBool(vout, "fullscreen");
-
-    sys->mouse = *m;
-
-    vlc_mutex_lock(&sys->display_lock);
-    /* Mouse events are only initialised if the display exists. */
-    if (sys->display != NULL && sys->mouse_event != NULL)
-        sys->mouse_event(m, sys->mouse_opaque);
-    vlc_mutex_unlock(&sys->display_lock);
+    if (mouse != m)
+        *mouse = *m;
 }
 
 void vout_PutSubpicture( vout_thread_t *vout, subpicture_t *subpic )
@@ -515,7 +481,7 @@ void vout_ChangeDisplayFilled(vout_thread_t *vout, bool is_filled)
     assert(!sys->dummy);
 
     vlc_mutex_lock(&sys->window_lock);
-    sys->display_cfg.is_display_filled = is_filled;
+    sys->display_cfg.display.autoscale = is_filled;
     /* no window size update here */
 
     vlc_mutex_lock(&sys->display_lock);
@@ -547,8 +513,8 @@ void vout_ChangeZoom(vout_thread_t *vout, unsigned num, unsigned den)
     }
 
     vlc_mutex_lock(&sys->window_lock);
-    sys->display_cfg.zoom.num = num;
-    sys->display_cfg.zoom.den = den;
+    sys->display_cfg.display.zoom.num = num;
+    sys->display_cfg.display.zoom.den = den;
 
     vout_UpdateWindowSizeLocked(sys);
 
@@ -688,7 +654,7 @@ static void VoutGetDisplayCfg(vout_thread_sys_t *p_vout, const video_format_t *f
     const int display_height = var_GetInteger(vout, "height");
     cfg->display.width   = display_width > 0  ? display_width  : 0;
     cfg->display.height  = display_height > 0 ? display_height : 0;
-    cfg->is_display_filled  = var_GetBool(vout, "autoscale");
+    cfg->display.autoscale = var_GetBool(vout, "autoscale");
     unsigned msar_num, msar_den;
     if (var_InheritURational(vout, &msar_num, &msar_den, "monitor-par") ||
         msar_num <= 0 || msar_den <= 0) {
@@ -700,19 +666,19 @@ static void VoutGetDisplayCfg(vout_thread_sys_t *p_vout, const video_format_t *f
     unsigned zoom_den = 1000;
     unsigned zoom_num = zoom_den * var_GetFloat(vout, "zoom");
     vlc_ureduce(&zoom_num, &zoom_den, zoom_num, zoom_den, 0);
-    cfg->zoom.num = zoom_num;
-    cfg->zoom.den = zoom_den;
-    cfg->align.vertical = VLC_VIDEO_ALIGN_CENTER;
-    cfg->align.horizontal = VLC_VIDEO_ALIGN_CENTER;
+    cfg->display.zoom.num = zoom_num;
+    cfg->display.zoom.den = zoom_den;
+    cfg->display.align.vertical = VLC_VIDEO_ALIGN_CENTER;
+    cfg->display.align.horizontal = VLC_VIDEO_ALIGN_CENTER;
     const int align_mask = var_GetInteger(vout, "align");
     if (align_mask & VOUT_ALIGN_LEFT)
-        cfg->align.horizontal = VLC_VIDEO_ALIGN_LEFT;
+        cfg->display.align.horizontal = VLC_VIDEO_ALIGN_LEFT;
     else if (align_mask & VOUT_ALIGN_RIGHT)
-        cfg->align.horizontal = VLC_VIDEO_ALIGN_RIGHT;
+        cfg->display.align.horizontal = VLC_VIDEO_ALIGN_RIGHT;
     if (align_mask & VOUT_ALIGN_TOP)
-        cfg->align.vertical = VLC_VIDEO_ALIGN_TOP;
+        cfg->display.align.vertical = VLC_VIDEO_ALIGN_TOP;
     else if (align_mask & VOUT_ALIGN_BOTTOM)
-        cfg->align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
+        cfg->display.align.vertical = VLC_VIDEO_ALIGN_BOTTOM;
 }
 
 /* */
@@ -1122,7 +1088,7 @@ static int PrerenderPicture(vout_thread_sys_t *sys, picture_t *filtered,
     video_format_t fmt_spu;
     if (do_dr_spu) {
         vout_display_place_t place;
-        vout_display_PlacePicture(&place, vd->source, vd->cfg);
+        vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
 
         fmt_spu = *vd->source;
         if (fmt_spu.i_width * fmt_spu.i_height < place.width * place.height) {
@@ -1619,10 +1585,14 @@ void vout_ChangeSpuRate(vout_thread_t *vout, size_t channel_id, float rate)
 static int vout_Start(vout_thread_sys_t *vout, vlc_video_context *vctx, const vout_configuration_t *cfg)
 {
     vout_thread_sys_t *sys = vout;
+    filter_chain_t *cs, *ci;
+
     assert(!sys->dummy);
 
-    sys->mouse_event = cfg->mouse_event;
-    sys->mouse_opaque = cfg->mouse_opaque;
+    vlc_mutex_lock(&sys->window_lock);
+    vout_display_window_SetMouseHandler(sys->display_cfg.window,
+                                        cfg->mouse_event, cfg->mouse_opaque);
+    vlc_mutex_unlock(&sys->window_lock);
 
     sys->decoder_fifo = picture_fifo_New();
     sys->private.display_pool = NULL;
@@ -1642,10 +1612,16 @@ static int vout_Start(vout_thread_sys_t *vout, vlc_video_context *vctx, const vo
         .video = &static_cbs,
         .sys = vout,
     };
-    sys->filter.chain_static = filter_chain_NewVideo(&vout->obj, true, &owner);
+
+    cs = filter_chain_NewVideo(&vout->obj, true, &owner);
 
     owner.video = &interactive_cbs;
-    sys->filter.chain_interactive = filter_chain_NewVideo(&vout->obj, true, &owner);
+    ci = filter_chain_NewVideo(&vout->obj, true, &owner);
+
+    vlc_mutex_lock(&sys->filter.lock);
+    sys->filter.chain_static = cs;
+    sys->filter.chain_interactive = ci;
+    vlc_mutex_unlock(&sys->filter.lock);
 
     vout_display_cfg_t dcfg;
     struct vout_crop crop;
@@ -1707,12 +1683,17 @@ static int vout_Start(vout_thread_sys_t *vout, vlc_video_context *vctx, const vo
     return VLC_SUCCESS;
 error:
     if (sys->filter.chain_interactive != NULL)
-    {
         DelAllFilterCallbacks(vout);
-        filter_chain_Delete(sys->filter.chain_interactive);
-    }
-    if (sys->filter.chain_static != NULL)
-        filter_chain_Delete(sys->filter.chain_static);
+    vlc_mutex_lock(&sys->filter.lock);
+    ci = sys->filter.chain_interactive;
+    cs = sys->filter.chain_static;
+    sys->filter.chain_interactive = NULL;
+    sys->filter.chain_static = NULL;
+    vlc_mutex_unlock(&sys->filter.lock);
+    if (ci != NULL)
+        filter_chain_Delete(ci);
+    if (cs != NULL)
+        filter_chain_Delete(cs);
     video_format_Clean(&sys->filter.src_fmt);
     if (sys->filter.src_vctx)
     {
@@ -1724,6 +1705,9 @@ error:
         picture_fifo_Delete(sys->decoder_fifo);
         sys->decoder_fifo = NULL;
     }
+    vlc_mutex_lock(&sys->window_lock);
+    vout_display_window_SetMouseHandler(sys->display_cfg.window, NULL, NULL);
+    vlc_mutex_unlock(&sys->window_lock);
     return VLC_EGENERIC;
 }
 
@@ -1768,6 +1752,7 @@ static void *Thread(void *object)
 static void vout_ReleaseDisplay(vout_thread_sys_t *vout)
 {
     vout_thread_sys_t *sys = vout;
+    filter_chain_t *ci, *cs;
 
     assert(sys->display != NULL);
 
@@ -1785,8 +1770,14 @@ static void vout_ReleaseDisplay(vout_thread_sys_t *vout)
 
     /* Destroy the video filters */
     DelAllFilterCallbacks(vout);
-    filter_chain_Delete(sys->filter.chain_interactive);
-    filter_chain_Delete(sys->filter.chain_static);
+    vlc_mutex_lock(&sys->filter.lock);
+    ci = sys->filter.chain_interactive;
+    cs = sys->filter.chain_static;
+    sys->filter.chain_interactive = NULL;
+    sys->filter.chain_static = NULL;
+    vlc_mutex_unlock(&sys->filter.lock);
+    filter_chain_Delete(ci);
+    filter_chain_Delete(cs);
     video_format_Clean(&sys->filter.src_fmt);
     if (sys->filter.src_vctx)
     {
@@ -1802,11 +1793,9 @@ static void vout_ReleaseDisplay(vout_thread_sys_t *vout)
     }
     assert(sys->private.display_pool == NULL);
 
-    if (sys->mouse_event)
-    {
-        sys->mouse_event(NULL, sys->mouse_opaque);
-        sys->mouse_event = NULL;
-    }
+    vlc_mutex_lock(&sys->window_lock);
+    vout_display_window_SetMouseHandler(sys->display_cfg.window, NULL, NULL);
+    vlc_mutex_unlock(&sys->window_lock);
 
     if (sys->spu)
         spu_Detach(sys->spu);


=====================================
src/video_output/video_window.c
=====================================
@@ -53,8 +53,18 @@ static void vlc_window_Ack(void *data)
 typedef struct vout_display_window
 {
     vout_thread_t *vout;
-    vlc_mouse_t mouse;
-    vlc_tick_t last_left_press;
+
+    video_format_t format;
+    struct vout_display_placement display;
+    vlc_mutex_t lock;
+
+    struct {
+        vlc_mouse_t window;
+        vlc_mouse_t video;
+        vlc_tick_t last_left_press;
+        vlc_mouse_event event;
+        void *opaque;
+    } mouse;
 } vout_display_window_t;
 
 static void vout_display_window_ResizeNotify(vlc_window_t *window,
@@ -66,6 +76,11 @@ static void vout_display_window_ResizeNotify(vlc_window_t *window,
     vout_thread_t *vout = state->vout;
     struct vlc_window_ack_data data = { window, cb, width, height, opaque };
 
+    vlc_mutex_lock(&state->lock);
+    state->display.width = width;
+    state->display.height = height;
+    vlc_mutex_unlock(&state->lock);
+
     msg_Dbg(window, "resized to %ux%u", width, height);
     vout_ChangeDisplaySize(vout, width, height, vlc_window_Ack, &data);
 }
@@ -121,7 +136,7 @@ static void vout_display_window_MouseEvent(vlc_window_t *window,
 {
     vout_display_window_t *state = window->owner.sys;
     vout_thread_t *vout = state->vout;
-    vlc_mouse_t *m = &state->mouse;
+    vlc_mouse_t *m = &state->mouse.window;
 
     m->b_double_click = false;
 
@@ -129,7 +144,7 @@ static void vout_display_window_MouseEvent(vlc_window_t *window,
     {
         case VLC_WINDOW_MOUSE_MOVED:
             vlc_mouse_SetPosition(m, ev->x, ev->y);
-            state->last_left_press = INT64_MIN;
+            state->mouse.last_left_press = INT64_MIN;
             break;
 
         case VLC_WINDOW_MOUSE_PRESSED:
@@ -139,14 +154,14 @@ static void vout_display_window_MouseEvent(vlc_window_t *window,
             {
                 const vlc_tick_t now = vlc_tick_now();
 
-                if (state->last_left_press != INT64_MIN
-                 && now - state->last_left_press < DOUBLE_CLICK_TIME)
+                if (state->mouse.last_left_press != INT64_MIN
+                 && now - state->mouse.last_left_press < DOUBLE_CLICK_TIME)
                 {
                     m->b_double_click = true;
-                    state->last_left_press = INT64_MIN;
+                    state->mouse.last_left_press = INT64_MIN;
                 }
                 else
-                    state->last_left_press = now;
+                    state->mouse.last_left_press = now;
             }
 
             vlc_mouse_SetPressed(m, ev->button_mask);
@@ -165,7 +180,34 @@ static void vout_display_window_MouseEvent(vlc_window_t *window,
             vlc_assert_unreachable();
     }
 
-    vout_MouseState(vout, m);
+    vlc_mouse_t video_mouse = *m;
+
+    vlc_mutex_lock(&state->lock);
+    if (likely(state->format.i_visible_width != 0
+            && state->format.i_visible_height != 0
+            && state->display.width != 0 && state->display.height != 0))
+        vout_display_TranslateCoordinates(&video_mouse.i_x, &video_mouse.i_y,
+                                          &state->format, &state->display);
+    vlc_mutex_unlock(&state->lock);
+
+    vout_FilterMouse(vout, &video_mouse);
+
+    /* Check if the mouse state actually changed and emit events. */
+    /* NOTE: sys->mouse is only used here, so no need to lock. */
+    if (vlc_mouse_HasMoved(&state->mouse.video, &video_mouse))
+        var_SetCoords(vout, "mouse-moved", m->i_x, m->i_y);
+    if (vlc_mouse_HasButton(&state->mouse.video, &video_mouse))
+        var_SetInteger(vout, "mouse-button-down", m->i_pressed);
+    if (m->b_double_click)
+        var_ToggleBool(vout, "fullscreen");
+
+    state->mouse.video = video_mouse;
+
+    vlc_mutex_lock(&state->lock);
+    /* Mouse events are only initialised if the display exists. */
+    if (state->mouse.event != NULL)
+        state->mouse.event(&video_mouse, state->mouse.opaque);
+    vlc_mutex_unlock(&state->lock);
 }
 
 static void vout_display_window_KeyboardEvent(vlc_window_t *window,
@@ -194,12 +236,31 @@ static const struct vlc_window_callbacks vout_display_window_cbs = {
     .output_event = vout_display_window_OutputEvent,
 };
 
+void vout_display_window_SetMouseHandler(vlc_window_t *window,
+                                         vlc_mouse_event event, void *opaque)
+{
+    vout_display_window_t *state = window->owner.sys;
+
+    /*
+     * Note that the current implementation of this function is technically
+     * reentrant, but better not rely on this in calling code.
+     */
+    vlc_mutex_lock(&state->lock);
+    if (state->mouse.event != NULL)
+        state->mouse.event(NULL, state->mouse.opaque);
+
+    state->mouse.event = event;
+    state->mouse.opaque = opaque;
+    vlc_mutex_unlock(&state->lock);
+}
+
+static
 void vout_display_SizeWindow(unsigned *restrict width,
                              unsigned *restrict height,
                              const video_format_t *restrict original,
                              const vlc_rational_t *restrict dar,
                              const struct vout_crop *restrict crop,
-                             const vout_display_cfg_t *restrict cfg)
+                             const struct vout_display_placement *restrict dp)
 {
     unsigned w = original->i_visible_width;
     unsigned h = original->i_visible_height;
@@ -239,8 +300,8 @@ void vout_display_SizeWindow(unsigned *restrict width,
             break;
     }
 
-    *width = cfg->display.width;
-    *height = cfg->display.height;
+    *width = dp->width;
+    *height = dp->height;
 
     /* If both width and height are forced, keep them as is. */
     if (*width != 0 && *height != 0)
@@ -258,8 +319,8 @@ void vout_display_SizeWindow(unsigned *restrict width,
         h = x;
     }
 
-    if (cfg->display.sar.num > 0 && cfg->display.sar.den > 0)
-        w = (w * cfg->display.sar.den) / cfg->display.sar.num;
+    if (dp->sar.num > 0 && dp->sar.den > 0)
+        w = (w * dp->sar.den) / dp->sar.num;
 
     /* If width is forced, adjust height according to the aspect ratio */
     if (*width != 0) {
@@ -274,8 +335,32 @@ void vout_display_SizeWindow(unsigned *restrict width,
     }
 
     /* If neither width nor height are forced, use the requested zoom. */
-    *width = (w * cfg->zoom.num) / cfg->zoom.den;
-    *height = (h * cfg->zoom.num) / cfg->zoom.den;
+    *width = (w * dp->zoom.num) / dp->zoom.den;
+    *height = (h * dp->zoom.num) / dp->zoom.den;
+}
+
+void vout_display_ResizeWindow(struct vlc_window *window,
+                               const video_format_t *restrict original,
+                               const vlc_rational_t *restrict dar,
+                               const struct vout_crop *restrict crop,
+                               const struct vout_display_placement *restrict dp)
+{
+    vout_display_window_t *state = window->owner.sys;
+    unsigned width, height;
+
+    vlc_mutex_lock(&state->lock);
+    video_format_Clean(&state->format);
+    video_format_Copy(&state->format, original);
+    width = state->display.width;
+    height = state->display.height;
+    state->display = *dp;
+    state->display.width = width;
+    state->display.height = height;
+    vlc_mutex_unlock(&state->lock);
+
+    vout_display_SizeWindow(&width, &height, original, dar, crop, dp);
+    msg_Dbg(window, "requested window size: %ux%u", width, height);
+    vlc_window_SetSize(window, width, height);
 }
 
 /**
@@ -287,8 +372,13 @@ vlc_window_t *vout_display_window_New(vout_thread_t *vout)
     if (state == NULL)
         return NULL;
 
-    vlc_mouse_Init(&state->mouse);
-    state->last_left_press = INT64_MIN;
+    video_format_Init(&state->format, 0);
+    state->display.width = state->display.height = 0;
+    vlc_mutex_init(&state->lock);
+    vlc_mouse_Init(&state->mouse.window);
+    vlc_mouse_Init(&state->mouse.video);
+    state->mouse.last_left_press = INT64_MIN;
+    state->mouse.event = NULL;
     state->vout = vout;
 
     char *modlist = var_InheritString(vout, "window");
@@ -330,5 +420,6 @@ void vout_display_window_Delete(vlc_window_t *window)
     var_Destroy(vout, "window-fullscreen-output");
     var_Destroy(vout, "window-fullscreen");
     var_Destroy(vout, "window-state");
+    video_format_Clean(&state->format);
     free(state);
 }


=====================================
src/video_output/video_window.h
=====================================
@@ -23,9 +23,10 @@ struct vout_crop;
 vlc_window_t *vout_display_window_New(vout_thread_t *);
 void vout_display_window_Delete(vlc_window_t *);
 
-void vout_display_SizeWindow(unsigned *restrict width,
-                             unsigned *restrict height,
-                             const video_format_t *restrict original,
-                             const vlc_rational_t *restrict dar,
-                             const struct vout_crop *restrict crop,
-                             const vout_display_cfg_t *restrict cfg);
+void vout_display_ResizeWindow(vlc_window_t *,
+                               const video_format_t *restrict original,
+                               const vlc_rational_t *restrict dar,
+                               const struct vout_crop *restrict crop,
+                               const struct vout_display_placement *restrict dp);
+void vout_display_window_SetMouseHandler(vlc_window_t *,
+                                         vlc_mouse_event, void *);


=====================================
src/video_output/vout_internal.h
=====================================
@@ -164,6 +164,8 @@ void vout_ControlChangeSubFilters(vout_thread_t *, const char *);
 void vout_ChangeSpuChannelMargin(vout_thread_t *, enum vlc_vout_order order, int);
 void vout_ChangeViewpoint( vout_thread_t *, const vlc_viewpoint_t *);
 
+void vout_FilterMouse(vout_thread_t *vout, vlc_mouse_t *mouse);
+
 /* */
 void vout_CreateVars( vout_thread_t * );
 void vout_IntfInit( vout_thread_t * );
@@ -212,11 +214,6 @@ void vout_ChangeSpuRate( vout_thread_t *, size_t channel_id, float rate );
 void vout_ChangeSpuDelay( vout_thread_t *, size_t channel_id, vlc_tick_t delay );
 
 
-/**
- * Updates the pointing device state.
- */
-void vout_MouseState(vout_thread_t *, const vlc_mouse_t *);
-
 /**
  * This function will return and reset internal statistics.
  */



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c36028fae5f3e30ad665dba1c15177049738c670...a2e0adec40bf9c6b8a34490e9c4b1ec12b8bbfff

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c36028fae5f3e30ad665dba1c15177049738c670...a2e0adec40bf9c6b8a34490e9c4b1ec12b8bbfff
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list