[vlc-devel] [PATCH] win32touch: provide touch support for 360 videos.

Pierre Lamot pierre at videolabs.io
Fri Nov 3 14:23:13 CET 2017


---
 modules/video_output/win32/events.c     |   3 +-
 modules/video_output/win32/win32touch.c | 398 ++++++++++++++++++++++----------
 modules/video_output/win32/win32touch.h |   8 +-
 3 files changed, 278 insertions(+), 131 deletions(-)

diff --git a/modules/video_output/win32/events.c b/modules/video_output/win32/events.c
index 7608007692..88e67acba3 100644
--- a/modules/video_output/win32/events.c
+++ b/modules/video_output/win32/events.c
@@ -805,7 +805,8 @@ static int Win32VoutCreateWindow( event_thread_t *p_event )
         return VLC_EGENERIC;
     }
 
-    InitGestures( p_event->hwnd, &p_event->p_gesture );
+    bool b_isProjected  = (vd->fmt.projection_mode != PROJECTION_MODE_RECTANGULAR);
+    InitGestures( p_event->hwnd, &p_event->p_gesture, b_isProjected );
 
     p_event->p_sensors = HookWindowsSensors(vd, p_event->hwnd);
 
diff --git a/modules/video_output/win32/win32touch.c b/modules/video_output/win32/win32touch.c
index 72f041b9d0..ece54d5708 100644
--- a/modules/video_output/win32/win32touch.c
+++ b/modules/video_output/win32/win32touch.c
@@ -31,6 +31,9 @@
 
 #include <assert.h>
 
+static BOOL DecodeGestureAction( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi );
+static BOOL DecodeGestureProjection( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi );
+
 LRESULT DecodeGesture( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture,
                        HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
 {
@@ -45,159 +48,294 @@ LRESULT DecodeGesture( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture,
     BOOL bHandled = FALSE; /* Needed to release the handle */
 
     if( bResult )
+        bHandled = p_gesture->DecodeGestureImpl(p_this, p_gesture, &gi);
+    else
+    {
+        DWORD dwErr = GetLastError();
+        if( dwErr > 0 )
+            msg_Err( p_this, "Could not retrieve a valid GESTUREINFO structure" );
+    }
+
+    if( bHandled )
+    {
+        /* Close the Handle, if we handled the gesture, a contrario
+         * from the doc example */
+        p_gesture->OurCloseGestureInfoHandle((HGESTUREINFO)lParam);
+        return 0;
+    }
+    else
+        return DefWindowProc( hWnd, message, wParam, lParam );
+}
+
+static BOOL DecodeGestureAction( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi )
+{
+    BOOL bHandled = FALSE; /* Needed to release the handle */
+    switch ( p_gi->dwID )
     {
-        switch ( gi.dwID )
-        {
-            case GID_BEGIN:
-                /* Set the win32_gesture_sys_t values */
-                p_gesture->i_beginx      = gi.ptsLocation.x;
-                p_gesture->i_beginy      = gi.ptsLocation.y;
-                p_gesture->i_lasty       = p_gesture->i_beginy;
-                p_gesture->b_2fingers    = false;
-                break;
-            case GID_END:
-                if( p_gesture->i_type != 0 &&
-                    p_gesture->i_action == GESTURE_ACTION_JUMP )
+        case GID_BEGIN:
+            /* Set the win32_gesture_sys_t values */
+            p_gesture->i_beginx      = p_gi->ptsLocation.x;
+            p_gesture->i_beginy      = p_gi->ptsLocation.y;
+            p_gesture->i_lasty       = p_gesture->i_beginy;
+            p_gesture->b_2fingers    = false;
+            break;
+        case GID_END:
+            if( p_gesture->i_type != 0 &&
+                p_gesture->i_action == GESTURE_ACTION_JUMP )
+            {
+                int action_id;
+                if( p_gesture->i_beginx > p_gi->ptsLocation.x )
                 {
-                    int action_id;
-                    if( p_gesture->i_beginx > gi.ptsLocation.x )
-                    {
-                        if( p_gesture->b_2fingers )
-                            action_id = ACTIONID_JUMP_BACKWARD_MEDIUM;
-                        else
-                            action_id = ACTIONID_JUMP_BACKWARD_SHORT;
-                    }
+                    if( p_gesture->b_2fingers )
+                        action_id = ACTIONID_JUMP_BACKWARD_MEDIUM;
                     else
-                    {
-                        if( p_gesture->b_2fingers )
-                            action_id = ACTIONID_JUMP_FORWARD_MEDIUM;
-                        else
-                            action_id = ACTIONID_JUMP_FORWARD_SHORT;
-                    }
-                    var_SetInteger( p_this->obj.libvlc, "key-action", action_id );
+                        action_id = ACTIONID_JUMP_BACKWARD_SHORT;
                 }
-                /* Reset the values */
-                p_gesture->i_action = GESTURE_ACTION_UNDEFINED;
-                p_gesture->i_type = p_gesture->i_beginx = p_gesture->i_beginy = -1;
-                p_gesture->b_2fingers = false;
-                break;
-            case GID_PAN:
-                p_gesture->i_type = GID_PAN;
-                bHandled = TRUE;
-
-                if( (DWORD)gi.ullArguments > 0 )
-                    p_gesture->b_2fingers = true;
-
-                if( p_gesture->i_action == GESTURE_ACTION_UNDEFINED )
+                else
                 {
-                    if( abs( p_gesture->i_beginx - gi.ptsLocation.x ) +
-                        abs( p_gesture->i_beginy - gi.ptsLocation.y ) > 50 )
-                    {
-                        if( abs( p_gesture->i_beginx - gi.ptsLocation.x ) >
-                            abs( p_gesture->i_beginy - gi.ptsLocation.y ) )
-                           p_gesture->i_action =  GESTURE_ACTION_JUMP;
-                        else if ( p_gesture->b_2fingers )
-                           p_gesture->i_action = GESTURE_ACTION_BRIGHTNESS;
-                        else
-                           p_gesture->i_action =  GESTURE_ACTION_VOLUME;
-                    }
+                    if( p_gesture->b_2fingers )
+                        action_id = ACTIONID_JUMP_FORWARD_MEDIUM;
+                    else
+                        action_id = ACTIONID_JUMP_FORWARD_SHORT;
                 }
+                var_SetInteger( p_this->obj.libvlc, "key-action", action_id );
+            }
+            /* Reset the values */
+            p_gesture->i_action = GESTURE_ACTION_UNDEFINED;
+            p_gesture->i_type = p_gesture->i_beginx = p_gesture->i_beginy = -1;
+            p_gesture->b_2fingers = false;
+            break;
+        case GID_PAN:
+            p_gesture->i_type = GID_PAN;
+            bHandled = TRUE;
 
-                if( p_gesture->i_action == GESTURE_ACTION_VOLUME )
-                {
-                    int offset = p_gesture->i_lasty - gi.ptsLocation.y;
+            if (p_gi->dwFlags & GF_BEGIN) {
+                p_gesture->i_beginx = p_gi->ptsLocation.x;
+                p_gesture->i_beginy = p_gi->ptsLocation.y;
+            }
 
-                    if( offset > 100)
-                        var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_UP );
-                    else if( offset < -100)
-                        var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_DOWN );
+            if( (DWORD)p_gi->ullArguments > 0 )
+                p_gesture->b_2fingers = true;
+
+            if( p_gesture->i_action == GESTURE_ACTION_UNDEFINED )
+            {
+                if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) +
+                    abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) > 50 )
+                {
+                    if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) >
+                        abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) )
+                       p_gesture->i_action =  GESTURE_ACTION_JUMP;
+                    else if ( p_gesture->b_2fingers )
+                       p_gesture->i_action = GESTURE_ACTION_BRIGHTNESS;
                     else
-                        break;
+                       p_gesture->i_action =  GESTURE_ACTION_VOLUME;
+                }
+            }
+
+            if( p_gesture->i_action == GESTURE_ACTION_VOLUME )
+            {
+                int offset = p_gesture->i_lasty - p_gi->ptsLocation.y;
+
+                if( offset > 100)
+                    var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_UP );
+                else if( offset < -100)
+                    var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_DOWN );
+                else
+                    break;
 
-                    p_gesture->i_lasty = gi.ptsLocation.y;
+                p_gesture->i_lasty = p_gi->ptsLocation.y;
+            }
+            else if ( p_gesture->i_action == GESTURE_ACTION_BRIGHTNESS )
+            {
+                /* Currently unimplemented
+                if( p_gesture->i_lasty == -1 )
+                    p_gesture->i_lasty = p_gesture->i_beginy;
+
+                if( p_gesture->i_lasty - p_gesture->i_beginy > 80 )
+                {
+                    var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_BRIGHTNESS_DOWN );
+                    p_gesture->i_lasty = p_gi->ptsLocation.y;
                 }
-                else if ( p_gesture->i_action == GESTURE_ACTION_BRIGHTNESS )
+                else if ( p_gesture->i_lasty - p_gesture->i_beginy < 80 )
                 {
-                    /* Currently unimplemented
-                    if( p_gesture->i_lasty == -1 )
-                        p_gesture->i_lasty = p_gesture->i_beginy;
-
-                    if( p_gesture->i_lasty - p_gesture->i_beginy > 80 )
+                    var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_BRIGHTNESS_UP );
+                    p_gesture->i_lasty = p_gi->ptsLocation.y;
+                } */
+            }
+            break;
+        case GID_TWOFINGERTAP:
+            p_gesture->i_type = GID_TWOFINGERTAP;
+            var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_PLAY_PAUSE );
+            bHandled = TRUE;
+            break;
+        case GID_ZOOM:
+            p_gesture->i_type = GID_ZOOM;
+            switch( p_gi->dwFlags )
+            {
+                case GF_BEGIN:
+                    p_gesture->i_ullArguments = p_gi->ullArguments;
+                    break;
+                case GF_END:
                     {
-                        var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_BRIGHTNESS_DOWN );
-                        p_gesture->i_lasty = gi.ptsLocation.y;
+                        double k = (double)(p_gi->ullArguments) /
+                                   (double)(p_gesture->i_ullArguments);
+                        if( k > 1 )
+                            var_SetInteger( p_this->obj.libvlc, "key-action",
+                                    ACTIONID_TOGGLE_FULLSCREEN );
+                        else
+                            var_SetInteger( p_this->obj.libvlc, "key-action",
+                                    ACTIONID_LEAVE_FULLSCREEN );
                     }
-                    else if ( p_gesture->i_lasty - p_gesture->i_beginy < 80 )
-                    {
-                        var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_BRIGHTNESS_UP );
-                        p_gesture->i_lasty = gi.ptsLocation.y;
-                    } */
+                    break;
+                default:
+                    msg_Err( p_this, "Unmanaged dwFlag: %lx", p_gi->dwFlags );
+            }
+            bHandled = TRUE;
+            break;
+        case WM_VSCROLL:
+            bHandled = TRUE;
+            break;
+        default:
+            break;
+    }
+    return bHandled;
+}
+
+
+static BOOL DecodeGestureProjection( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi )
+{
+    //vout_display_t *vd = (vout_display_t *)p_this;
+
+    BOOL bHandled = FALSE; /* Needed to release the handle */
+    switch ( p_gi->dwID )
+    {
+        case GID_BEGIN:
+            /* Set the win32_gesture_sys_t values */
+            p_gesture->i_beginx      = p_gi->ptsLocation.x;
+            p_gesture->i_beginy      = p_gi->ptsLocation.y;
+            p_gesture->i_lasty       = p_gesture->i_beginy;
+            p_gesture->b_2fingers    = false;
+            break;
+        case GID_END:
+            if( p_gesture->i_type != 0 &&
+                p_gesture->i_action == GESTURE_ACTION_JUMP )
+            {
+                int action_id;
+                if( p_gesture->b_2fingers )
+                {
+                    if( p_gesture->i_beginx > p_gi->ptsLocation.x )
+                        action_id = ACTIONID_JUMP_BACKWARD_SHORT;
+                    else
+                        action_id = ACTIONID_JUMP_FORWARD_SHORT;
+                    var_SetInteger( p_this->obj.libvlc, "key-action", action_id );
                 }
-                break;
-            case GID_TWOFINGERTAP:
-                p_gesture->i_type = GID_TWOFINGERTAP;
-                var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_PLAY_PAUSE );
-                bHandled = TRUE;
-                break;
-            case GID_ZOOM:
-                p_gesture->i_type = GID_ZOOM;
-                switch( gi.dwFlags )
+            }
+            /* Reset the values */
+            p_gesture->i_action = GESTURE_ACTION_UNDEFINED;
+            p_gesture->i_type = p_gesture->i_beginx = p_gesture->i_beginy = -1;
+            p_gesture->b_2fingers = false;
+            break;
+        case GID_PAN:
+            //vd->cfg->display.width;
+            p_gesture->i_type = GID_PAN;
+            bHandled = TRUE;
+            if (p_gi->dwFlags & GF_BEGIN) {
+                p_gesture->i_beginx = p_gi->ptsLocation.x;
+                p_gesture->i_beginy = p_gi->ptsLocation.y;
+            }
+
+            if( (DWORD)p_gi->ullArguments > 0 )
+                p_gesture->b_2fingers = true;
+
+            if( p_gesture->b_2fingers && p_gesture->i_action == GESTURE_ACTION_UNDEFINED )
+            {
+                if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) +
+                    abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) > 50 )
                 {
-                    case GF_BEGIN:
-                        p_gesture->i_ullArguments = gi.ullArguments;
-                        break;
-                    case GF_END:
-                        {
-                            double k = (double)(gi.ullArguments) /
-                                       (double)(p_gesture->i_ullArguments);
-                            if( k > 1 )
-                                var_SetInteger( p_this->obj.libvlc, "key-action",
-                                        ACTIONID_TOGGLE_FULLSCREEN );
-                            else
-                                var_SetInteger( p_this->obj.libvlc, "key-action",
-                                        ACTIONID_LEAVE_FULLSCREEN );
-                        }
-                        break;
-                    default:
-                        msg_Err( p_this, "Unmanaged dwFlag: %lx", gi.dwFlags );
+                    if( abs( p_gesture->i_beginx - p_gi->ptsLocation.x ) >
+                        abs( p_gesture->i_beginy - p_gi->ptsLocation.y ) )
+                        p_gesture->i_action =  GESTURE_ACTION_JUMP;
+                    else
+                        p_gesture->i_action =  GESTURE_ACTION_VOLUME;
                 }
-                bHandled = TRUE;
-                break;
-            case WM_VSCROLL:
-                bHandled = TRUE;
-                break;
-            default:
-                break;
-        }
-    }
-    else
-    {
-        DWORD dwErr = GetLastError();
-        if( dwErr > 0 )
-            msg_Err( p_this, "Could not retrieve a valid GESTUREINFO structure" );
-    }
+            }
 
+            if( p_gesture->i_action == GESTURE_ACTION_VOLUME )
+            {
+                int offset = p_gesture->i_lasty - p_gi->ptsLocation.y;
 
-    if( bHandled )
-    {
-        /* Close the Handle, if we handled the gesture, a contrario
-         * from the doc example */
-        p_gesture->OurCloseGestureInfoHandle((HGESTUREINFO)lParam);
-        return 0;
+                if( offset > 100)
+                    var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_UP );
+                else if( offset < -100)
+                    var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VOL_DOWN );
+                else
+                    break;
+
+                p_gesture->i_lasty = p_gi->ptsLocation.y;
+            }
+            break;
+        case GID_TWOFINGERTAP:
+            p_gesture->i_type = GID_TWOFINGERTAP;
+            var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_PLAY_PAUSE );
+            bHandled = TRUE;
+            break;
+        case GID_ZOOM:
+            p_gesture->i_type = GID_ZOOM;
+            bHandled = TRUE;
+            switch( p_gi->dwFlags )
+            {
+                case GF_BEGIN:
+                    p_gesture->i_ullArguments = p_gi->ullArguments;
+                    p_gesture->f_lastzoom = 1.0;
+                    break;
+                default:
+                {
+                    double k = (double)(p_gi->ullArguments) /
+                               (double)(p_gesture->i_ullArguments);
+
+                    if (k > p_gesture->f_lastzoom * 1.01)
+                    {
+                        var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VIEWPOINT_FOV_IN );
+                        p_gesture->f_lastzoom = k;
+                    }
+                    else if (k < p_gesture->f_lastzoom * 0.99)
+                    {
+                        var_SetInteger( p_this->obj.libvlc, "key-action", ACTIONID_VIEWPOINT_FOV_OUT );
+                        p_gesture->f_lastzoom = k;
+                    }
+                    break;
+                }
+            }
+            break;
+        case WM_VSCROLL:
+            bHandled = TRUE;
+            break;
+        default:
+            break;
     }
-    else
-        return DefWindowProc( hWnd, message, wParam, lParam );
+    return bHandled;
 }
 
-BOOL InitGestures( HWND hwnd, win32_gesture_sys_t **pp_gesture )
+BOOL InitGestures( HWND hwnd, win32_gesture_sys_t **pp_gesture, bool b_isProjected )
 {
     BOOL result = FALSE;
     GESTURECONFIG config = { 0, 0, 0 };
-    config.dwID    = GID_PAN;
-    config.dwWant  = GC_PAN |
-                     GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY |
-                     GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
-    config.dwBlock = GC_PAN_WITH_INERTIA;
+    if (b_isProjected)
+    {
+        //don't handle single finger pan in projected mode, it will be interpreted
+        //as mouse events.
+        config.dwID    = GID_PAN;
+        config.dwWant  = GC_PAN;
+        config.dwBlock = GC_PAN_WITH_INERTIA;
+    }
+    else
+    {
+        config.dwID    = GID_PAN;
+        config.dwWant  = GC_PAN |
+                         GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY |
+                         GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
+        config.dwBlock = GC_PAN_WITH_INERTIA;
+    }
 
     win32_gesture_sys_t *p_gesture = malloc( sizeof(win32_gesture_sys_t) );
     if( !p_gesture )
@@ -231,6 +369,10 @@ BOOL InitGestures( HWND hwnd, win32_gesture_sys_t **pp_gesture )
                 sizeof( GESTURECONFIG )
                 );
     }
+    if (b_isProjected)
+        p_gesture->DecodeGestureImpl = DecodeGestureProjection;
+    else
+        p_gesture->DecodeGestureImpl = DecodeGestureAction;
 
     p_gesture->i_type     = 0;
     p_gesture->b_2fingers = false;
diff --git a/modules/video_output/win32/win32touch.h b/modules/video_output/win32/win32touch.h
index 8e86eaec2b..ea854282bf 100644
--- a/modules/video_output/win32/win32touch.h
+++ b/modules/video_output/win32/win32touch.h
@@ -52,24 +52,28 @@ enum {
     GESTURE_ACTION_BRIGHTNESS
 };
 
-typedef struct {
+
+typedef struct win32_gesture_sys_t {
     DWORD       i_type;                 /* Gesture ID */
     int         i_action;               /* GESTURE_ACTION */
 
     int         i_beginx;               /* Start X position */
     int         i_beginy;               /* Start Y position */
     int         i_lasty;                /* Last known Y position for PAN */
+    double      f_lastzoom;             /* Last zoom factor */
 
     ULONGLONG   i_ullArguments;         /* Base values to compare between 2 zoom gestures */
     bool        b_2fingers;             /* Did we detect 2 fingers? */
 
+    BOOL (*DecodeGestureImpl)( vlc_object_t *p_this, struct win32_gesture_sys_t *p_gesture, const GESTUREINFO* p_gi );
+
     HINSTANCE   huser_dll;              /* user32.dll */
     BOOL (WINAPI * OurCloseGestureInfoHandle)(HGESTUREINFO hGestureInfo);
     BOOL (WINAPI * OurGetGestureInfo)(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo);
 } win32_gesture_sys_t;
 
 
-BOOL InitGestures( HWND hwnd, win32_gesture_sys_t **p_gesture );
+BOOL InitGestures( HWND hwnd, win32_gesture_sys_t **p_gesture, bool b_isProjected );
 
 LRESULT DecodeGesture( vlc_object_t *p_intf, win32_gesture_sys_t *p_gesture,
         HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
-- 
2.14.2



More information about the vlc-devel mailing list