#include <vlc_es.h>
#include <vlc_picture.h>
#include <vlc_subpicture.h>
+#include <vlc_mouse.h>
/**
* \file
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
*/
*/
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 */
--- /dev/null
+/*****************************************************************************
+ * 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 */
+
/* List of filters */
vlc_array_t filters;
+ vlc_array_t mouses;
/* Capability of all the filters in the chain */
char *psz_capability;
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;
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 );
}
}
}
+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,
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 );
/* 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 );
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;
}