Added mouse support to filter_t and filter_chain_t.

This commit is contained in:
Laurent Aimar 2009-06-02 21:38:46 +02:00
parent 7b9914e2c0
commit 5f175d3295
4 changed files with 209 additions and 0 deletions

View File

@ -28,6 +28,7 @@
#include <vlc_es.h> #include <vlc_es.h>
#include <vlc_picture.h> #include <vlc_picture.h>
#include <vlc_subpicture.h> #include <vlc_subpicture.h>
#include <vlc_mouse.h>
/** /**
* \file * \file
@ -71,6 +72,18 @@ struct filter_t
int ( *pf_render_html ) ( filter_t *, subpicture_region_t *, int ( *pf_render_html ) ( filter_t *, subpicture_region_t *,
subpicture_region_t * ); subpicture_region_t * );
/* Filter mouse state.
*
* If non NULL, you must convert from output format to input format,
* if VLC_SUCCESS is returned, the mouse state is then propagated.
* If NULL, the mouse state is considered unchanged and will be
* propagated.
*
* If VLC_SUCCESS is not returned, the mouse changes are not propagated.
*/
int ( *pf_mouse )( filter_t *, vlc_mouse_t *,
const vlc_mouse_t *p_old,
const vlc_mouse_t *p_new );
/* /*
* Buffers allocation * Buffers allocation
*/ */
@ -312,5 +325,15 @@ VLC_EXPORT( block_t *, filter_chain_AudioFilter, ( filter_chain_t *, block_t * )
*/ */
VLC_EXPORT( void, filter_chain_SubFilter, ( filter_chain_t *, mtime_t ) ); VLC_EXPORT( void, filter_chain_SubFilter, ( filter_chain_t *, mtime_t ) );
/**
* Apply the filter chain to a mouse state.
*
* It will be applied from the output to the input. It makes sense only
* for a video filter chain.
*
* The vlc_mouse_t* pointers may be the same.
*/
VLC_EXPORT( int, filter_chain_MouseFilter, ( filter_chain_t *, vlc_mouse_t *, const vlc_mouse_t * ) );
#endif /* _VLC_FILTER_H */ #endif /* _VLC_FILTER_H */

145
include/vlc_mouse.h Normal file
View File

@ -0,0 +1,145 @@
/*****************************************************************************
* vlc_mouse.h: mouse related structures and functions
*****************************************************************************
* Copyright (C) 2009 Laurent Aimar
* $Id$
*
* Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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_MOUSE_H
#define _VLC_MOUSE_H 1
/**
* Mouse button
*/
enum
{
MOUSE_BUTTON_LEFT,
MOUSE_BUTTON_CENTER,
MOUSE_BUTTON_RIGHT,
MOUSE_BUTTON_WHEEL_UP,
MOUSE_BUTTON_WHEEL_DOWN,
};
/**
* Mouse state
*/
typedef struct
{
/* Coordinate */
int i_x;
int i_y;
/* Mask of pressed button */
int i_pressed;
/* Is double clicked */
bool b_double_click;
} vlc_mouse_t;
static inline void vlc_mouse_Init( vlc_mouse_t *p_mouse )
{
p_mouse->i_x = 0;
p_mouse->i_y = 0;
p_mouse->i_pressed = 0;
p_mouse->b_double_click = false;
}
/* */
static inline void vlc_mouse_SetPressed( vlc_mouse_t *p_mouse,
int i_button )
{
p_mouse->i_pressed |= 1 << i_button;
}
static inline void vlc_mouse_SetReleased( vlc_mouse_t *p_mouse,
int i_button )
{
p_mouse->i_pressed &= ~(1 << i_button);
}
static inline void vlc_mouse_SetPosition( vlc_mouse_t *p_mouse,
int i_x, int i_y )
{
p_mouse->i_x = i_x;
p_mouse->i_y = i_y;
}
/* */
static inline bool vlc_mouse_IsPressed( const vlc_mouse_t *p_mouse,
int i_button )
{
return ( p_mouse->i_pressed & (1 << i_button) ) != 0;
}
static inline bool vlc_mouse_IsLeftPressed( const vlc_mouse_t *p_mouse )
{
return vlc_mouse_IsPressed( p_mouse, MOUSE_BUTTON_LEFT );
}
static inline bool vlc_mouse_IsCenterPressed( const vlc_mouse_t *p_mouse )
{
return vlc_mouse_IsPressed( p_mouse, MOUSE_BUTTON_CENTER );
}
static inline bool vlc_mouse_IsRightPressed( const vlc_mouse_t *p_mouse )
{
return vlc_mouse_IsPressed( p_mouse, MOUSE_BUTTON_RIGHT );
}
static inline bool vlc_mouse_IsWheelUpPressed( const vlc_mouse_t *p_mouse )
{
return vlc_mouse_IsPressed( p_mouse, MOUSE_BUTTON_WHEEL_UP );
}
static inline bool vlc_mouse_IsWheelDownPressed( const vlc_mouse_t *p_mouse )
{
return vlc_mouse_IsPressed( p_mouse, MOUSE_BUTTON_WHEEL_DOWN );
}
static inline void vlc_mouse_GetMotion( int *pi_x, int *pi_y,
const vlc_mouse_t *p_old,
const vlc_mouse_t *p_new )
{
*pi_x = p_new->i_x - p_old->i_x;
*pi_y = p_new->i_y - p_old->i_y;
}
/* */
static inline bool vlc_mouse_HasChanged( const vlc_mouse_t *p_old,
const vlc_mouse_t *p_new )
{
return p_old->i_x != p_new->i_x || p_old->i_x != p_new->i_x ||
p_old->i_pressed != p_new->i_pressed;
}
static inline bool vlc_mouse_HasMoved( const vlc_mouse_t *p_old,
const vlc_mouse_t *p_new )
{
return p_old->i_x != p_new->i_x || p_old->i_y != p_new->i_y;
}
static inline bool vlc_mouse_HasButton( const vlc_mouse_t *p_old,
const vlc_mouse_t *p_new )
{
return p_old->i_pressed != p_new->i_pressed;
}
static inline bool vlc_mouse_HasPressed( const vlc_mouse_t *p_old,
const vlc_mouse_t *p_new,
int i_button )
{
const int i_mask = 1 << i_button;
return (p_old->i_pressed & i_mask) == 0 && (p_new->i_pressed & i_mask);
}
static inline bool vlc_mouse_HasReleased( const vlc_mouse_t *p_old,
const vlc_mouse_t *p_new,
int i_button )
{
const int i_mask = 1 << i_button;
return (p_old->i_pressed & i_mask) && (p_new->i_pressed & i_mask) == 0;
}
#endif /* _VLC_MOUSE_H */

View File

@ -130,6 +130,7 @@ filter_chain_DeleteFilter
filter_chain_GetFilter filter_chain_GetFilter
filter_chain_GetFmtOut filter_chain_GetFmtOut
filter_chain_GetLength filter_chain_GetLength
filter_chain_MouseFilter
__filter_chain_New __filter_chain_New
filter_chain_Reset filter_chain_Reset
filter_chain_SubFilter filter_chain_SubFilter

View File

@ -60,6 +60,7 @@ struct filter_chain_t
/* List of filters */ /* List of filters */
vlc_array_t filters; vlc_array_t filters;
vlc_array_t mouses;
/* Capability of all the filters in the chain */ /* Capability of all the filters in the chain */
char *psz_capability; char *psz_capability;
@ -106,9 +107,11 @@ filter_chain_t *__filter_chain_New( vlc_object_t *p_this,
p_chain->p_this = p_this; p_chain->p_this = p_this;
vlc_array_init( &p_chain->filters ); vlc_array_init( &p_chain->filters );
vlc_array_init( &p_chain->mouses );
p_chain->psz_capability = strdup( psz_capability ); p_chain->psz_capability = strdup( psz_capability );
if( !p_chain->psz_capability ) if( !p_chain->psz_capability )
{ {
vlc_array_clear( &p_chain->mouses );
vlc_array_clear( &p_chain->filters ); vlc_array_clear( &p_chain->filters );
free( p_chain ); free( p_chain );
return NULL; return NULL;
@ -135,6 +138,7 @@ void filter_chain_Delete( filter_chain_t *p_chain )
es_format_Clean( &p_chain->fmt_out ); es_format_Clean( &p_chain->fmt_out );
free( p_chain->psz_capability ); free( p_chain->psz_capability );
vlc_array_clear( &p_chain->mouses );
vlc_array_clear( &p_chain->filters ); vlc_array_clear( &p_chain->filters );
free( p_chain ); free( p_chain );
} }
@ -290,6 +294,31 @@ void filter_chain_SubFilter( filter_chain_t *p_chain,
} }
} }
int filter_chain_MouseFilter( filter_chain_t *p_chain, vlc_mouse_t *p_dst, const vlc_mouse_t *p_src )
{
vlc_mouse_t current = *p_src;
for( int i = vlc_array_count( &p_chain->filters ) - 1; i >= 0; i-- )
{
filter_t *p_filter = vlc_array_item_at_index( &p_chain->filters, i );
vlc_mouse_t *p_mouse = vlc_array_item_at_index( &p_chain->mouses, i );
if( p_filter->pf_mouse && p_mouse )
{
vlc_mouse_t old = *p_mouse;
vlc_mouse_t filtered;
*p_mouse = current;
if( p_filter->pf_mouse( p_filter, &filtered, &old, &current ) )
return VLC_EGENERIC;
current = filtered;
}
}
*p_dst = current;
return VLC_SUCCESS;
}
/* Helpers */ /* Helpers */
static filter_t *filter_chain_AppendFilterInternal( filter_chain_t *p_chain, static filter_t *filter_chain_AppendFilterInternal( filter_chain_t *p_chain,
@ -343,6 +372,11 @@ static filter_t *filter_chain_AppendFilterInternal( filter_chain_t *p_chain,
vlc_array_append( &p_chain->filters, p_filter ); vlc_array_append( &p_chain->filters, p_filter );
vlc_mouse_t *p_mouse = malloc( sizeof(*p_mouse) );
if( p_mouse )
vlc_mouse_Init( p_mouse );
vlc_array_append( &p_chain->mouses, p_mouse );
msg_Dbg( p_chain->p_this, "Filter '%s' (%p) appended to chain", msg_Dbg( p_chain->p_this, "Filter '%s' (%p) appended to chain",
psz_name ? psz_name : p_filter->psz_object_name, p_filter ); psz_name ? psz_name : p_filter->psz_object_name, p_filter );
@ -416,6 +450,7 @@ static int filter_chain_DeleteFilterInternal( filter_chain_t *p_chain,
/* Remove it from the chain */ /* Remove it from the chain */
vlc_array_remove( &p_chain->filters, i_filter_idx ); vlc_array_remove( &p_chain->filters, i_filter_idx );
msg_Dbg( p_chain->p_this, "Filter '%s' (%p) removed from chain", msg_Dbg( p_chain->p_this, "Filter '%s' (%p) removed from chain",
p_filter->psz_object_name, p_filter ); p_filter->psz_object_name, p_filter );
@ -430,6 +465,11 @@ static int filter_chain_DeleteFilterInternal( filter_chain_t *p_chain,
module_unneed( p_filter, p_filter->p_module ); module_unneed( p_filter, p_filter->p_module );
vlc_object_release( p_filter ); vlc_object_release( p_filter );
vlc_mouse_t *p_mouse = vlc_array_item_at_index( &p_chain->mouses, i_filter_idx );
if( p_mouse )
free( p_mouse );
vlc_array_remove( &p_chain->mouses, i_filter_idx );
/* FIXME: check fmt_in/fmt_out consitency */ /* FIXME: check fmt_in/fmt_out consitency */
return VLC_SUCCESS; return VLC_SUCCESS;
} }