mirror of
https://code.videolan.org/videolan/vlc
synced 2024-10-07 03:56:28 +02:00
Add Win32 gestures helper
This is a helper to take action on touchscreens on Windows 7 or later It uses the braindead WM_GESTURE API and supports volume, seek (1 and 2 fingers), play/pause (2finger touch) and fullscreen (zoom gesture) The API is simple so other UI element can use it, notably Qt and the vouts This has been edited by jb too Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
This commit is contained in:
parent
2581bd185d
commit
20c8e19ed3
242
modules/control/win32touch.c
Normal file
242
modules/control/win32touch.c
Normal file
@ -0,0 +1,242 @@
|
||||
/*****************************************************************************
|
||||
* win32touch.c: touch gestures recognition
|
||||
*****************************************************************************
|
||||
* Copyright © 2013-2014 VideoLAN
|
||||
*
|
||||
* Authors: Ludovic Fauvet <etix@videolan.org>
|
||||
* Jean-Baptiste Kempf <jb@videolan.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "win32touch.h"
|
||||
|
||||
#include <vlc_keys.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
LRESULT DecodeGesture( vlc_object_t *p_this, win32_gesture_sys_t *p_gesture,
|
||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if( !p_gesture )
|
||||
return DefWindowProc( hWnd, message, wParam, lParam );
|
||||
|
||||
GESTUREINFO gi;
|
||||
ZeroMemory( &gi, sizeof( GESTUREINFO ) );
|
||||
gi.cbSize = sizeof( GESTUREINFO );
|
||||
|
||||
BOOL bResult = p_gesture->OurGetGestureInfo((HGESTUREINFO)lParam, &gi);
|
||||
BOOL bHandled = FALSE; /* Needed to release the handle */
|
||||
|
||||
if( bResult )
|
||||
{
|
||||
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 = -1;
|
||||
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 > gi.ptsLocation.x )
|
||||
{
|
||||
if( p_gesture->b_2fingers )
|
||||
action_id = ACTIONID_JUMP_BACKWARD_MEDIUM;
|
||||
else
|
||||
action_id = ACTIONID_JUMP_BACKWARD_SHORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p_gesture->b_2fingers )
|
||||
action_id = ACTIONID_JUMP_FORWARD_MEDIUM;
|
||||
else
|
||||
action_id = ACTIONID_JUMP_FORWARD_SHORT;
|
||||
}
|
||||
var_SetInteger( p_this->p_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( (DWORD)gi.ullArguments > 0 )
|
||||
p_gesture->b_2fingers = true;
|
||||
|
||||
if( p_gesture->i_action == GESTURE_ACTION_UNDEFINED )
|
||||
{
|
||||
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->i_action == GESTURE_ACTION_VOLUME )
|
||||
{
|
||||
int offset = p_gesture->i_beginy - gi.ptsLocation.y;
|
||||
if( offset > 0 )
|
||||
var_SetInteger( p_this->p_libvlc, "key-action", ACTIONID_VOL_UP );
|
||||
else
|
||||
var_SetInteger( p_this->p_libvlc, "key-action", ACTIONID_VOL_DOWN );
|
||||
}
|
||||
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->p_libvlc, "key-action", ACTIONID_BRIGHTNESS_DOWN );
|
||||
p_gesture->i_lasty = gi.ptsLocation.y;
|
||||
}
|
||||
else if ( p_gesture->i_lasty - p_gesture->i_beginy < 80 )
|
||||
{
|
||||
var_SetInteger( p_this->p_libvlc, "key-action", ACTIONID_BRIGHTNESS_UP );
|
||||
p_gesture->i_lasty = gi.ptsLocation.y;
|
||||
} */
|
||||
}
|
||||
break;
|
||||
case GID_TWOFINGERTAP:
|
||||
p_gesture->i_type = GID_TWOFINGERTAP;
|
||||
var_SetInteger( p_this->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
|
||||
bHandled = TRUE;
|
||||
break;
|
||||
case GID_ZOOM:
|
||||
p_gesture->i_type = GID_ZOOM;
|
||||
switch( gi.dwFlags )
|
||||
{
|
||||
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->p_libvlc, "key-action",
|
||||
ACTIONID_TOGGLE_FULLSCREEN );
|
||||
else
|
||||
var_SetInteger( p_this->p_libvlc, "key-action",
|
||||
ACTIONID_LEAVE_FULLSCREEN );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
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( 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 );
|
||||
}
|
||||
|
||||
BOOL InitGestures( HWND hwnd, win32_gesture_sys_t **pp_gesture )
|
||||
{
|
||||
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;
|
||||
|
||||
win32_gesture_sys_t *p_gesture = malloc( sizeof(win32_gesture_sys_t) );
|
||||
if( !p_gesture )
|
||||
{
|
||||
*pp_gesture = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HINSTANCE h_user32_dll = LoadLibrary(TEXT("user32.dll"));
|
||||
if( !h_user32_dll )
|
||||
{
|
||||
*pp_gesture = NULL;
|
||||
free( p_gesture );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL (WINAPI *OurSetGestureConfig) (HWND, DWORD, UINT, PGESTURECONFIG, UINT);
|
||||
OurSetGestureConfig = (void *)GetProcAddress(h_user32_dll, "SetGestureConfig");
|
||||
|
||||
p_gesture->OurCloseGestureInfoHandle =
|
||||
(void *)GetProcAddress(h_user32_dll, "CloseGestureInfoHandle" );
|
||||
p_gesture->OurGetGestureInfo =
|
||||
(void *)GetProcAddress(h_user32_dll, "GetGestureInfo");
|
||||
if( OurSetGestureConfig )
|
||||
{
|
||||
result = OurSetGestureConfig(
|
||||
hwnd,
|
||||
0,
|
||||
1,
|
||||
&config,
|
||||
sizeof( GESTURECONFIG )
|
||||
);
|
||||
}
|
||||
|
||||
p_gesture->i_type = 0;
|
||||
p_gesture->b_2fingers = false;
|
||||
p_gesture->i_action = GESTURE_ACTION_UNDEFINED;
|
||||
p_gesture->i_beginx = p_gesture->i_beginy = -1;
|
||||
p_gesture->i_lasty = -1;
|
||||
p_gesture->huser_dll = h_user32_dll;
|
||||
|
||||
*pp_gesture = p_gesture;
|
||||
return result;
|
||||
}
|
||||
|
||||
void CloseGestures( win32_gesture_sys_t *p_gesture )
|
||||
{
|
||||
if (p_gesture && p_gesture->huser_dll )
|
||||
FreeLibrary( p_gesture->huser_dll );
|
||||
free( p_gesture );
|
||||
}
|
83
modules/control/win32touch.h
Normal file
83
modules/control/win32touch.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*****************************************************************************
|
||||
* win32touch.c: touch gestures recognition
|
||||
*****************************************************************************
|
||||
* Copyright © 2013-2014 VideoLAN
|
||||
*
|
||||
* Authors: Ludovic Fauvet <etix@videolan.org>
|
||||
* Jean-Baptiste Kempf <jb@videolan.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef VLC_GESTURE_H_
|
||||
#define VLC_GESTURE_H_
|
||||
|
||||
# ifdef _WIN32_WINNT
|
||||
# undef _WIN32_WINNT
|
||||
# endif
|
||||
# define _WIN32_WINNT 0x0601
|
||||
# include <windows.h>
|
||||
# include <winuser.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <vlc_common.h>
|
||||
|
||||
#ifndef WM_GESTURE
|
||||
# define WM_GESTURE 0x0119
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
GESTURE_ACTION_UNDEFINED = 0,
|
||||
GESTURE_ACTION_VOLUME,
|
||||
GESTURE_ACTION_JUMP,
|
||||
GESTURE_ACTION_BRIGHTNESS
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
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 */
|
||||
|
||||
ULONGLONG i_ullArguments; /* Base values to compare between 2 zoom gestures */
|
||||
bool b_2fingers; /* Did we detect 2 fingers? */
|
||||
|
||||
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 );
|
||||
|
||||
LRESULT DecodeGesture( vlc_object_t *p_intf, win32_gesture_sys_t *p_gesture,
|
||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
void CloseGestures( win32_gesture_sys_t *p_gesture );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user