From: Laurent Aimar Date: Tue, 2 Jun 2009 19:38:46 +0000 (+0200) Subject: Added mouse support to filter_t and filter_chain_t. X-Git-Tag: 1.1.0-ff~5615 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=5f175d3295914f033dabca058fca86edef25d7b2;p=vlc Added mouse support to filter_t and filter_chain_t. --- diff --git a/include/vlc_filter.h b/include/vlc_filter.h index 6dbb2f117c..2bcc8c9aff 100644 --- a/include/vlc_filter.h +++ b/include/vlc_filter.h @@ -28,6 +28,7 @@ #include #include #include +#include /** * \file @@ -71,6 +72,18 @@ struct filter_t int ( *pf_render_html ) ( filter_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 */ @@ -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 ) ); +/** + * 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 */ diff --git a/include/vlc_mouse.h b/include/vlc_mouse.h new file mode 100644 index 0000000000..dff2129424 --- /dev/null +++ b/include/vlc_mouse.h @@ -0,0 +1,145 @@ +/***************************************************************************** + * vlc_mouse.h: mouse related structures and functions + ***************************************************************************** + * Copyright (C) 2009 Laurent Aimar + * $Id$ + * + * Authors: Laurent Aimar + * + * 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 */ + diff --git a/src/libvlccore.sym b/src/libvlccore.sym index bd116a8d67..89bb140149 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -130,6 +130,7 @@ filter_chain_DeleteFilter filter_chain_GetFilter filter_chain_GetFmtOut filter_chain_GetLength +filter_chain_MouseFilter __filter_chain_New filter_chain_Reset filter_chain_SubFilter diff --git a/src/misc/filter_chain.c b/src/misc/filter_chain.c index c2b14f9f31..d7de8805f0 100644 --- a/src/misc/filter_chain.c +++ b/src/misc/filter_chain.c @@ -60,6 +60,7 @@ struct filter_chain_t /* List of filters */ vlc_array_t filters; + vlc_array_t mouses; /* Capability of all the filters in the chain */ char *psz_capability; @@ -106,9 +107,11 @@ filter_chain_t *__filter_chain_New( vlc_object_t *p_this, p_chain->p_this = p_this; vlc_array_init( &p_chain->filters ); + vlc_array_init( &p_chain->mouses ); p_chain->psz_capability = strdup( psz_capability ); if( !p_chain->psz_capability ) { + vlc_array_clear( &p_chain->mouses ); vlc_array_clear( &p_chain->filters ); free( p_chain ); return NULL; @@ -135,6 +138,7 @@ void filter_chain_Delete( filter_chain_t *p_chain ) es_format_Clean( &p_chain->fmt_out ); free( p_chain->psz_capability ); + vlc_array_clear( &p_chain->mouses ); vlc_array_clear( &p_chain->filters ); 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, ¤t ) ) + return VLC_EGENERIC; + current = filtered; + } + } + + *p_dst = current; + return VLC_SUCCESS; +} + /* Helpers */ 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_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", 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 */ vlc_array_remove( &p_chain->filters, i_filter_idx ); + msg_Dbg( p_chain->p_this, "Filter '%s' (%p) removed from chain", 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 ); 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 */ return VLC_SUCCESS; }