Added mouse support to filter_t and filter_chain_t.
authorLaurent Aimar <fenrir@videolan.org>
Tue, 2 Jun 2009 19:38:46 +0000 (21:38 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Wed, 3 Jun 2009 20:34:48 +0000 (22:34 +0200)
include/vlc_filter.h
include/vlc_mouse.h [new file with mode: 0644]
src/libvlccore.sym
src/misc/filter_chain.c

index 6dbb2f1..2bcc8c9 100644 (file)
@@ -28,6 +28,7 @@
 #include <vlc_es.h>
 #include <vlc_picture.h>
 #include <vlc_subpicture.h>
+#include <vlc_mouse.h>
 
 /**
  * \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 (file)
index 0000000..dff2129
--- /dev/null
@@ -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 */
+
index bd116a8..89bb140 100644 (file)
@@ -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
index c2b14f9..d7de880 100644 (file)
@@ -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, &current ) )
+                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;
 }