[vlc-commits] window: pass mouse state directly from window to filters

Rémi Denis-Courmont git at videolan.org
Sun May 20 19:51:09 CEST 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri May 18 19:35:42 2018 +0300| [c3c376c3c04528023ca30c92bb86e9191b3e82af] | committer: Rémi Denis-Courmont

window: pass mouse state directly from window to filters

Avoid a pointless round-trip to the display.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c3c376c3c04528023ca30c92bb86e9191b3e82af
---

 src/video_output/control.h       |  5 ++--
 src/video_output/video_output.c  | 63 ++++++++++++++++------------------------
 src/video_output/vout_internal.h | 10 +++----
 src/video_output/window.c        | 55 +++++++++++++++++++++++++++++++++--
 4 files changed, 85 insertions(+), 48 deletions(-)

diff --git a/src/video_output/control.h b/src/video_output/control.h
index 04a66e9fb4..7b753f3cc2 100644
--- a/src/video_output/control.h
+++ b/src/video_output/control.h
@@ -24,7 +24,6 @@
 #ifndef LIBVLC_VOUT_INTERNAL_CONTROL_H
 #define LIBVLC_VOUT_INTERNAL_CONTROL_H
 
-#include <vlc_vout_window.h>
 #include <vlc_viewpoint.h>
 
 /* */
@@ -54,7 +53,7 @@ enum {
 
     VOUT_CONTROL_FULLSCREEN,            /* bool */
     VOUT_CONTROL_WINDOW_STATE,          /* unsigned */
-    VOUT_CONTROL_WINDOW_MOUSE,          /* window_mouse */
+    VOUT_CONTROL_MOUSE_STATE,           /* vlc_mouse_t */
     VOUT_CONTROL_DISPLAY_FILLED,        /* bool */
     VOUT_CONTROL_ZOOM,                  /* pair */
 
@@ -98,7 +97,7 @@ typedef struct {
             unsigned width;
             unsigned height;
         } window;
-        vout_window_mouse_event_t window_mouse;
+        vlc_mouse_t mouse;
         const vout_configuration_t *cfg;
         subpicture_t *subpicture;
         vlc_viewpoint_t viewpoint;
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 4d10566d91..9e8dd6e56b 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -359,13 +359,12 @@ 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)
+void vout_MouseState(vout_thread_t *vout, const vlc_mouse_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_cmd_Init(&cmd, VOUT_CONTROL_MOUSE_STATE);
+    cmd.u.mouse = *mouse;
 
     vout_control_Push(&vout->p->control, &cmd);
 }
@@ -1390,43 +1389,31 @@ static void ThreadChangeWindowState(vout_thread_t *vout, unsigned state)
 #endif
 }
 
-static void ThreadChangeWindowMouse(vout_thread_t *vout,
-                                    const vout_window_mouse_event_t *mouse)
+static void ThreadTranslateMouseState(vout_thread_t *vout,
+                                      const vlc_mouse_t *win_mouse)
 {
     vout_display_t *vd = vout->p->display.vd;
-    switch (mouse->type)
-    {
-        case VOUT_WINDOW_MOUSE_MOVED:
-        {
-            vout_display_place_t place;
-            vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
+    vlc_mouse_t vid_mouse;
+    vout_display_place_t place;
 
-            if (place.width <= 0 || place.height <= 0)
-                return;
+    /* Translate window coordinates to video coordinates */
+    vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
 
-            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 (place.width <= 0 || place.height <= 0)
+        return;
 
-            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:
-            if (mouse->button_mask == 0)
-                vout_display_SendEventMouseDoubleClick(vd);
-            break;
-        default: vlc_assert_unreachable();
-            break;
-    }
+    const int x = vd->source.i_x_offset
+        + (int64_t)(win_mouse->i_x - place.x)
+          * vd->source.i_visible_width / place.width;
+    const int y = vd->source.i_y_offset
+        + (int64_t)(win_mouse->i_y - place.y)
+          * vd->source.i_visible_height / place.height;
+
+    vid_mouse = *win_mouse;
+    vlc_mouse_SetPosition(&vid_mouse, x, y);
+
+    /* Then pass up the filter chains. */
+    vout_SendDisplayEventMouse(vout, &vid_mouse);
 }
 
 static void ThreadChangeDisplayFilled(vout_thread_t *vout, bool is_filled)
@@ -1740,8 +1727,8 @@ 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);
+    case VOUT_CONTROL_MOUSE_STATE:
+        ThreadTranslateMouseState(vout, &cmd.u.mouse);
         break;
     case VOUT_CONTROL_DISPLAY_FILLED:
         ThreadChangeDisplayFilled(vout, cmd.u.boolean);
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 89c7542943..ce57fc71e8 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -218,8 +218,6 @@ int spu_ProcessMouse(spu_t *, const vlc_mouse_t *, const video_format_t *);
 void spu_Attach( spu_t *, vlc_object_t *input, bool );
 void spu_ChangeMargin(spu_t *, int);
 
-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
@@ -227,6 +225,11 @@ typedef struct vout_window_mouse_event_t vout_window_mouse_event_t;
 void vout_ChangePause( vout_thread_t *, bool b_paused, mtime_t i_date );
 
 /**
+ * Updates the pointing device state.
+ */
+void vout_MouseState(vout_thread_t *, const vlc_mouse_t *);
+
+/**
  * This function will apply an offset on subtitle subpicture.
  */
 void spu_OffsetSubtitleDate( spu_t *p_spu, mtime_t i_duration );
@@ -259,9 +262,6 @@ 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 62a5f1248d..9ea5890ae9 100644
--- a/src/video_output/window.c
+++ b/src/video_output/window.c
@@ -125,11 +125,15 @@ void vout_window_SetInhibition(vout_window_t *window, bool enabled)
 #include "window.h"
 #include "event.h"
 
+#define DOUBLE_CLICK_TIME (3 * CLOCK_FREQ / 10)
+
 typedef struct vout_display_window
 {
     vout_display_t *vd;
     unsigned width;
     unsigned height;
+    vlc_mouse_t mouse;
+    mtime_t last_left_press;
 
     vlc_mutex_t lock;
 } vout_display_window_t;
@@ -157,10 +161,55 @@ static void vout_display_window_CloseNotify(vout_window_t *window)
 }
 
 static void vout_display_window_MouseEvent(vout_window_t *window,
-                                           const vout_window_mouse_event_t *mouse)
+                                           const vout_window_mouse_event_t *ev)
 {
+    vout_display_window_t *state = window->owner.sys;
     vout_thread_t *vout = (vout_thread_t *)window->obj.parent;
-    vout_WindowMouseEvent(vout, mouse);
+    vlc_mouse_t *m = &state->mouse;
+
+    m->b_double_click = false;
+
+    switch (ev->type)
+    {
+        case VOUT_WINDOW_MOUSE_MOVED:
+            vlc_mouse_SetPosition(m, ev->x, ev->y);
+            state->last_left_press = INT64_MIN;
+            break;
+
+        case VOUT_WINDOW_MOUSE_PRESSED:
+            if (!window->info.has_double_click
+             && ev->button_mask == MOUSE_BUTTON_LEFT
+             && !vlc_mouse_IsLeftPressed(m))
+            {
+                const mtime_t now = mdate();
+
+                if (state->last_left_press != INT64_MIN
+                 && now - state->last_left_press < DOUBLE_CLICK_TIME)
+                {
+                    m->b_double_click = true;
+                    state->last_left_press = INT64_MIN;
+                }
+                else
+                    state->last_left_press = now;
+            }
+
+            vlc_mouse_SetPressed(m, ev->button_mask);
+            break;
+
+        case VOUT_WINDOW_MOUSE_RELEASED:
+            vlc_mouse_SetReleased(m, ev->button_mask);
+            break;
+
+        case VOUT_WINDOW_MOUSE_DOUBLE_CLICK:
+            assert(window->info.has_double_click);
+            m->b_double_click = true;
+            break;
+
+        default:
+            vlc_assert_unreachable();
+    }
+
+    vout_MouseState(vout, m);
 }
 
 static void vout_display_window_KeyboardEvent(vout_window_t *window,
@@ -191,6 +240,8 @@ vout_window_t *vout_display_window_New(vout_thread_t *vout,
     state->vd = NULL;
     state->width = cfg->width;
     state->height = cfg->height;
+    vlc_mouse_Init(&state->mouse);
+    state->last_left_press = INT64_MIN;
     vlc_mutex_init(&state->lock);
 
     char *modlist = var_InheritString(vout, "window");



More information about the vlc-commits mailing list