Commit d9f560ed authored by Laurent Aimar's avatar Laurent Aimar

Fixed a lot of issues regarding fullscreen/mouse in vout-filter.

Please stress the vout-filters and report any regressions.
parent 75cfa806
...@@ -49,8 +49,10 @@ static void Render ( vout_thread_t *, picture_t * ); ...@@ -49,8 +49,10 @@ static void Render ( vout_thread_t *, picture_t * );
static void RemoveAllVout ( vout_thread_t *p_vout ); static void RemoveAllVout ( vout_thread_t *p_vout );
static int SendEvents( vlc_object_t *, char const *, static int FullscreenEventUp( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
static int FullscreenEventDown( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -213,8 +215,7 @@ static int Create( vlc_object_t *p_this ) ...@@ -213,8 +215,7 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index, i_vout; int i_vout;
picture_t *p_pic;
char *psz_default_vout; char *psz_default_vout;
video_format_t fmt; video_format_t fmt;
...@@ -265,14 +266,12 @@ static int Init( vout_thread_t *p_vout ) ...@@ -265,14 +266,12 @@ static int Init( vout_thread_t *p_vout )
RemoveAllVout( p_vout ); RemoveAllVout( p_vout );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
vout_filter_SetupChild( p_vout, p_vout->p_sys->pp_vout[i_vout],
ADD_CALLBACKS( p_vout->p_sys->pp_vout[ i_vout ], SendEvents ); NULL, FullscreenEventUp, FullscreenEventDown, true );
} }
free( psz_default_vout ); free( psz_default_vout );
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -282,18 +281,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -282,18 +281,9 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index;
DEL_PARENT_CALLBACKS( SendEventsToChild );
/* Free the fake output buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
RemoveAllVout( p_vout ); RemoveAllVout( p_vout );
vout_filter_ReleaseDirectBuffers( p_vout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -380,43 +370,64 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -380,43 +370,64 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
*****************************************************************************/ *****************************************************************************/
static void RemoveAllVout( vout_thread_t *p_vout ) static void RemoveAllVout( vout_thread_t *p_vout )
{ {
while( p_vout->p_sys->i_clones ) vout_sys_t *p_sys = p_vout->p_sys;
while( p_sys->i_clones )
{ {
--p_vout->p_sys->i_clones; p_sys->i_clones--;
DEL_CALLBACKS( p_vout->p_sys->pp_vout[p_vout->p_sys->i_clones],
SendEvents ); vout_filter_SetupChild( p_vout, p_sys->pp_vout[p_sys->i_clones],
vout_CloseAndRelease( p_vout->p_sys->pp_vout[p_vout->p_sys->i_clones] ); NULL, FullscreenEventUp, FullscreenEventDown, false );
vout_CloseAndRelease( p_sys->pp_vout[p_sys->i_clones] );
} }
} }
/***************************************************************************** /**
* SendEvents: forward mouse and keyboard events to the parent p_vout * Forward fullscreen event to/from the childrens.
*****************************************************************************/ * FIXME pretty much duplicated from wall.c
static int SendEvents( vlc_object_t *p_this, char const *psz_var, */
vlc_value_t oldval, vlc_value_t newval, void *p_data ) static bool IsFullscreenActive( vout_thread_t *p_vout )
{ {
VLC_UNUSED(p_this); VLC_UNUSED(oldval); vout_sys_t *p_sys = p_vout->p_sys;
var_Set( (vlc_object_t *)p_data, psz_var, newval ); for( int i = 0; i < p_sys->i_clones; i++ )
{
if( var_GetBool( p_sys->pp_vout[i], "fullscreen" ) )
return true;
}
return false;
}
static int FullscreenEventUp( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
vout_thread_t *p_vout = p_data;
VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(newval);
const bool b_fullscreen = IsFullscreenActive( p_vout );
if( !var_GetBool( p_vout, "fullscreen" ) != !b_fullscreen )
return var_SetBool( p_vout, "fullscreen", b_fullscreen );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int FullscreenEventDown( vlc_object_t *p_this, char const *psz_var,
/***************************************************************************** vlc_value_t oldval, vlc_value_t newval, void *p_data )
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
VLC_UNUSED(p_data); VLC_UNUSED(oldval); vout_thread_t *p_vout = (vout_thread_t*)p_this;
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_sys_t *p_sys = p_vout->p_sys;
int i_vout; VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_var);
for( i_vout = 0; i_vout < p_vout->p_sys->i_clones; i_vout++ ) const bool b_fullscreen = IsFullscreenActive( p_vout );
if( !b_fullscreen != !newval.b_bool )
{ {
var_Set( p_vout->p_sys->pp_vout[ i_vout ], psz_var, newval ); for( int i = 0; i < p_sys->i_clones; i++ )
{
if( !strcmp( psz_var, "fullscreen" ) ) break; vout_thread_t *p_child = p_sys->pp_vout[i];
if( !var_GetBool( p_child, "fullscreen" ) != !newval.b_bool )
{
var_SetBool( p_child, "fullscreen", newval.b_bool );
if( newval.b_bool )
return VLC_SUCCESS;
}
}
} }
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -56,7 +56,7 @@ static void Render ( vout_thread_t *, picture_t * ); ...@@ -56,7 +56,7 @@ static void Render ( vout_thread_t *, picture_t * );
static void UpdateStats ( vout_thread_t *, picture_t * ); static void UpdateStats ( vout_thread_t *, picture_t * );
static int SendEvents( vlc_object_t *, char const *, static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
#ifdef BEST_AUTOCROP #ifdef BEST_AUTOCROP
...@@ -200,9 +200,7 @@ static int Create( vlc_object_t *p_this ) ...@@ -200,9 +200,7 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index;
char *psz_var; char *psz_var;
picture_t *p_pic;
video_format_t fmt; video_format_t fmt;
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
...@@ -384,11 +382,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -384,11 +382,9 @@ static int Init( vout_thread_t *p_vout )
var_AddCallback( p_vout, "ratio-crop", FilterCallback, NULL ); var_AddCallback( p_vout, "ratio-crop", FilterCallback, NULL );
#endif #endif
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -398,21 +394,15 @@ static int Init( vout_thread_t *p_vout ) ...@@ -398,21 +394,15 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index; vout_sys_t *p_sys = p_vout->p_sys;
DEL_PARENT_CALLBACKS( SendEventsToChild );
if( p_vout->p_sys->p_vout )
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
/* Free the fake output buffers we allocated */ if( p_sys->p_vout )
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{ {
i_index--; vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig ); vout_CloseAndRelease( p_sys->p_vout );
} }
if( p_vout->p_sys->p_vout ) vout_filter_ReleaseDirectBuffers( p_vout );
vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -455,7 +445,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -455,7 +445,7 @@ static int Manage( vout_thread_t *p_vout )
if( p_vout->p_sys->p_vout ) if( p_vout->p_sys->p_vout )
{ {
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_DelChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
vout_CloseAndRelease( p_vout->p_sys->p_vout ); vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
...@@ -475,7 +465,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -475,7 +465,7 @@ static int Manage( vout_thread_t *p_vout )
_("VLC could not open the video output module.") ); _("VLC could not open the video output module.") );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
p_vout->p_sys->b_changed = false; p_vout->p_sys->b_changed = false;
p_vout->p_sys->i_lastchange = 0; p_vout->p_sys->i_lastchange = 0;
...@@ -829,41 +819,23 @@ static void UpdateStats( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -829,41 +819,23 @@ static void UpdateStats( vout_thread_t *p_vout, picture_t *p_pic )
p_vout->p_sys->b_changed = true; p_vout->p_sys->b_changed = true;
} }
/***************************************************************************** /**
* SendEvents: forward mouse and keyboard events to the parent p_vout * Forward mouse event with proper conversion.
*****************************************************************************/ */
static int SendEvents( vlc_object_t *p_this, char const *psz_var, static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *_p_vout ) vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
vout_thread_t *p_vout = p_data;
VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
vlc_value_t sentval = newval;
/* Translate the mouse coordinates */ /* Translate the mouse coordinates
* FIXME missing lock */
if( !strcmp( psz_var, "mouse-x" ) ) if( !strcmp( psz_var, "mouse-x" ) )
{ newval.i_int += p_vout->p_sys->i_x;
sentval.i_int += p_vout->p_sys->i_x;
}
else if( !strcmp( psz_var, "mouse-y" ) ) else if( !strcmp( psz_var, "mouse-y" ) )
{ newval.i_int += p_vout->p_sys->i_y;
sentval.i_int += p_vout->p_sys->i_y;
}
var_Set( p_vout, psz_var, sentval ); return var_Set( p_vout, psz_var, newval );
return VLC_SUCCESS;
}
/*****************************************************************************
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
} }
#ifdef BEST_AUTOCROP #ifdef BEST_AUTOCROP
......
...@@ -64,6 +64,9 @@ static int Init ( vout_thread_t * ); ...@@ -64,6 +64,9 @@ static int Init ( vout_thread_t * );
static void End ( vout_thread_t * ); static void End ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * ); static void Render ( vout_thread_t *, picture_t * );
static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data );
static void RenderDiscard( vout_thread_t *, picture_t *, picture_t *, int ); static void RenderDiscard( vout_thread_t *, picture_t *, picture_t *, int );
static void RenderBob ( vout_thread_t *, picture_t *, picture_t *, int ); static void RenderBob ( vout_thread_t *, picture_t *, picture_t *, int );
static void RenderMean ( vout_thread_t *, picture_t *, picture_t * ); static void RenderMean ( vout_thread_t *, picture_t *, picture_t * );
...@@ -91,9 +94,6 @@ static void EndMMX ( void ); ...@@ -91,9 +94,6 @@ static void EndMMX ( void );
static void End3DNow ( void ); static void End3DNow ( void );
#endif #endif
static int SendEvents ( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method ); static void SetFilterMethod( vout_thread_t *p_vout, char *psz_method );
static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout ); static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout );
...@@ -363,9 +363,6 @@ static bool IsChromaSupported( vlc_fourcc_t i_chroma ) ...@@ -363,9 +363,6 @@ static bool IsChromaSupported( vlc_fourcc_t i_chroma )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index;
picture_t *p_pic;
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
if( !IsChromaSupported( p_vout->render.i_chroma ) ) if( !IsChromaSupported( p_vout->render.i_chroma ) )
...@@ -392,11 +389,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -392,11 +389,9 @@ static int Init( vout_thread_t *p_vout )
var_AddCallback( p_vout, "deinterlace-mode", FilterCallback, NULL ); var_AddCallback( p_vout, "deinterlace-mode", FilterCallback, NULL );
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
ADD_PARENT_CALLBACKS( SendEventsToChild ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -419,22 +414,15 @@ static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout ) ...@@ -419,22 +414,15 @@ static vout_thread_t *SpawnRealVout( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index; vout_sys_t *p_sys = p_vout->p_sys;
DEL_PARENT_CALLBACKS( SendEventsToChild );
if( p_vout->p_sys->p_vout )
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
/* Free the fake output buffers we allocated */ if( p_sys->p_vout )
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{ {
i_index--; vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig ); vout_CloseAndRelease( p_sys->p_vout );
} }
if( p_vout->p_sys->p_vout ) vout_filter_ReleaseDirectBuffers( p_vout );
vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -449,6 +437,21 @@ static void Destroy( vlc_object_t *p_this ) ...@@ -449,6 +437,21 @@ static void Destroy( vlc_object_t *p_this )
free( p_vout->p_sys ); free( p_vout->p_sys );
} }
/**
* Forward mouse event with proper conversion.
*/
static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
vout_thread_t *p_vout = p_data;
VLC_UNUSED(p_this); VLC_UNUSED(oldval);
if( !strcmp( psz_var, "mouse-y" ) && p_vout->p_sys->b_half_height )
newval.i_int *= 2;
return var_Set( p_vout, psz_var, newval );
}
/***************************************************************************** /*****************************************************************************
* Render: displays previously rendered output * Render: displays previously rendered output
***************************************************************************** *****************************************************************************
...@@ -1669,24 +1672,6 @@ static void RenderX( picture_t *p_outpic, picture_t *p_pic ) ...@@ -1669,24 +1672,6 @@ static void RenderX( picture_t *p_outpic, picture_t *p_pic )
#endif #endif
} }
/*****************************************************************************
* SendEvents: forward mouse and keyboard events to the parent p_vout
*****************************************************************************/
static int SendEvents( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *_p_vout )
{
VLC_UNUSED(p_this); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
vlc_value_t sentval = newval;
if( !strcmp( psz_var, "mouse-y" ) && p_vout->p_sys->b_half_height )
sentval.i_int *= 2;
var_Set( p_vout, psz_var, sentval );
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* FilterCallback: called when changing the deinterlace method on the fly. * FilterCallback: called when changing the deinterlace method on the fly.
*****************************************************************************/ *****************************************************************************/
...@@ -1713,7 +1698,7 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -1713,7 +1698,7 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,
/* We need to kill the old vout */ /* We need to kill the old vout */
if( p_vout->p_sys->p_vout ) if( p_vout->p_sys->p_vout )
{ {
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_DelChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
vout_CloseAndRelease( p_vout->p_sys->p_vout ); vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
...@@ -1729,25 +1714,12 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd, ...@@ -1729,25 +1714,12 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,
return VLC_EGENERIC; return VLC_EGENERIC;
} }
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
vlc_mutex_unlock( &p_vout->p_sys->filter_lock ); vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* video filter2 functions * video filter2 functions
*****************************************************************************/ *****************************************************************************/
......
...@@ -21,86 +21,120 @@ ...@@ -21,86 +21,120 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/ *****************************************************************************/
#define ALLOCATE_DIRECTBUFFERS( i_max ) \ /**
/* Try to initialize i_max direct buffers */ \ * Initialize i_max direct buffers for a vout_thread_t.
while( I_OUTPUTPICTURES < ( i_max ) ) \ */
{ \ static inline void vout_filter_AllocateDirectBuffers( vout_thread_t *p_vout, int i_max )
p_pic = NULL; \ {
\ I_OUTPUTPICTURES = 0;
/* Find an empty picture slot */ \
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) \
{ \
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) \
{ \
p_pic = p_vout->p_picture + i_index; \
break; \
} \
} \
\
if( p_pic == NULL ) \
{ \
break; \
} \
\
/* Allocate the picture */ \
vout_AllocatePicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma, \
p_vout->output.i_width, \
p_vout->output.i_height, \
p_vout->output.i_aspect ); \
\
if( !p_pic->i_planes ) \
{ \
break; \
} \
\
p_pic->i_status = DESTROYED_PICTURE; \
p_pic->i_type = DIRECT_PICTURE; \
\
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; \
\
I_OUTPUTPICTURES++; \
} \
/***************************************************************************** /* Try to initialize i_max direct buffers */
* SetParentVal: forward variable value to parent whithout triggering the while( I_OUTPUTPICTURES < i_max )
* callback {
*****************************************************************************/ picture_t *p_pic = NULL;
static int SetParentVal( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data ) /* Find an empty picture slot */
for( int i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
}
}
if( p_pic == NULL )
break;
/* Allocate the picture */
vout_AllocatePicture( VLC_OBJECT(p_vout), p_pic, p_vout->output.i_chroma,
p_vout->output.i_width,
p_vout->output.i_height,
p_vout->output.i_aspect );
if( !p_pic->i_planes )
break;
p_pic->i_status = DESTROYED_PICTURE;
p_pic->i_type = DIRECT_PICTURE;
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
I_OUTPUTPICTURES++;
}
}
static inline void vout_filter_ReleaseDirectBuffers( vout_thread_t *p_vout )
{
for( int i_index = I_OUTPUTPICTURES-1; i_index >= 0; i_index-- )
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
/**
* Internal helper to forward an event from p_this to p_data
*/
static inline int ForwardEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(oldval);
var_Change( (vlc_object_t *)p_data, psz_var, VLC_VAR_SETVALUE, vlc_object_t *p_dst = (vlc_object_t*)p_data;
&newval, NULL );
return var_Set( p_dst, psz_var, newval );
}
/**
* Internal helper to forward fullscreen event from p_this to p_data.
*/
static inline int ForwardFullscreen( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_this); VLC_UNUSED(oldval);
vlc_object_t *p_dst = (vlc_object_t*)p_data;
if( !var_GetBool( p_dst, "fullscreen" ) != !newval.b_bool )
return var_SetBool( p_dst, psz_var, newval.b_bool );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/**
* Install/remove all callbacks needed for proper event handling inside
* a vout-filter.
*/
static inline void vout_filter_SetupChild( vout_thread_t *p_parent, vout_thread_t *p_child,
vlc_callback_t pf_mouse_event,
vlc_callback_t pf_fullscreen_up,
vlc_callback_t pf_fullscreen_down,
bool b_init )
{
int (*pf_execute)( vlc_object_t *, const char *, vlc_callback_t, void * );
if( b_init )
pf_execute = __var_AddCallback;
else
pf_execute = __var_DelCallback;
/* */
if( !pf_mouse_event )
pf_mouse_event = ForwardEvent;
pf_execute( VLC_OBJECT(p_child), "mouse-x", pf_mouse_event, p_parent );
pf_execute( VLC_OBJECT(p_child), "mouse-y", pf_mouse_event, p_parent );
pf_execute( VLC_OBJECT(p_child), "mouse-moved", pf_mouse_event, p_parent );
pf_execute( VLC_OBJECT(p_child), "mouse-clicked", pf_mouse_event, p_parent );
pf_execute( VLC_OBJECT(p_child), "mouse-button-down", pf_mouse_event, p_parent );
/* */
pf_execute( VLC_OBJECT(p_parent), "autoscale", ForwardEvent, p_child );
pf_execute( VLC_OBJECT(p_parent), "scale", ForwardEvent, p_child );
pf_execute( VLC_OBJECT(p_parent), "aspect-ratio", ForwardEvent, p_child );
pf_execute( VLC_OBJECT(p_parent), "crop", ForwardEvent, p_child );
/* */
if( !pf_fullscreen_up )
pf_fullscreen_up = ForwardFullscreen;
if( !pf_fullscreen_down )
pf_fullscreen_down = ForwardFullscreen;
pf_execute( VLC_OBJECT(p_child), "fullscreen", pf_fullscreen_up, p_parent );
pf_execute( VLC_OBJECT(p_parent), "fullscreen", pf_fullscreen_down, p_child );
}
#define vout_filter_AddChild( a, b, c ) vout_filter_SetupChild( a, b, c, NULL, NULL, true )
#define vout_filter_DelChild( a, b, c ) vout_filter_SetupChild( a, b, c, NULL, NULL, false )
#define ADD_CALLBACKS( newvout, handler ) \
var_AddCallback( newvout, "fullscreen", SetParentVal, p_vout ); \
var_AddCallback( newvout, "mouse-x", SendEvents, p_vout ); \
var_AddCallback( newvout, "mouse-y", SendEvents, p_vout ); \
var_AddCallback( newvout, "mouse-moved", SendEvents, p_vout ); \
var_AddCallback( newvout, "mouse-clicked", SendEvents, p_vout );
#define DEL_CALLBACKS( newvout, handler ) \
var_DelCallback( newvout, "fullscreen", SetParentVal, p_vout ); \
var_DelCallback( newvout, "mouse-x", SendEvents, p_vout ); \
var_DelCallback( newvout, "mouse-y", SendEvents, p_vout ); \
var_DelCallback( newvout, "mouse-moved", SendEvents, p_vout ); \
var_DelCallback( newvout, "mouse-clicked", SendEvents, p_vout );
#define ADD_PARENT_CALLBACKS( handler ) \
var_AddCallback( p_vout, "fullscreen", handler, NULL ); \
var_AddCallback( p_vout, "autoscale", handler, NULL ); \
var_AddCallback( p_vout, "scale", handler, NULL ); \
var_AddCallback( p_vout, "aspect-ratio", handler, NULL ); \
var_AddCallback( p_vout, "crop", handler, NULL );
#define DEL_PARENT_CALLBACKS( handler ) \
var_DelCallback( p_vout, "fullscreen", handler, NULL ); \
var_DelCallback( p_vout, "autoscale", handler, NULL ); \
var_DelCallback( p_vout, "scale", handler, NULL ); \
var_DelCallback( p_vout, "aspect-ratio", handler, NULL ); \
var_DelCallback( p_vout, "crop", handler, NULL );
static int SendEventsToChild( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_vout.h> #include <vlc_vout.h>
#include <assert.h>
#include "vlc_filter.h" #include "vlc_filter.h"
#include "filter_common.h" #include "filter_common.h"
...@@ -53,8 +54,6 @@ static int Init ( vout_thread_t * ); ...@@ -53,8 +54,6 @@ static int Init ( vout_thread_t * );
static void End ( vout_thread_t * ); static void End ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * ); static void Render ( vout_thread_t *, picture_t * );
static int SendEvents( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int MouseEvent( vlc_object_t *, char const *, static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t , vlc_value_t , void * ); vlc_value_t , vlc_value_t , void * );
static int Control ( vout_thread_t *, int, va_list ); static int Control ( vout_thread_t *, int, va_list );
...@@ -364,7 +363,6 @@ static int Init( vout_thread_t *p_vout ) ...@@ -364,7 +363,6 @@ static int Init( vout_thread_t *p_vout )
{ {
vout_sys_t *p_sys = p_vout->p_sys; vout_sys_t *p_sys = p_vout->p_sys;
picture_t *p_pic; picture_t *p_pic;
int i_index;
video_format_t fmt; video_format_t fmt;
logo_list_t *p_logo_list = p_sys->p_logo_list; logo_list_t *p_logo_list = p_sys->p_logo_list;
...@@ -459,12 +457,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -459,12 +457,9 @@ static int Init( vout_thread_t *p_vout )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
var_AddCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
var_AddCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout);
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AddChild( p_vout, p_sys->p_vout, MouseEvent );
ADD_CALLBACKS( p_sys->p_vout, SendEvents );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -475,24 +470,12 @@ static int Init( vout_thread_t *p_vout ) ...@@ -475,24 +470,12 @@ static int Init( vout_thread_t *p_vout )
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
vout_sys_t *p_sys = p_vout->p_sys; vout_sys_t *p_sys = p_vout->p_sys;
int i_index;
DEL_PARENT_CALLBACKS( SendEventsToChild );
DEL_CALLBACKS( p_sys->p_vout, SendEvents );
/* Free the fake output buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
var_DelCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout);
var_DelCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout);
vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
vout_CloseAndRelease( p_sys->p_vout ); vout_CloseAndRelease( p_sys->p_vout );
vout_filter_ReleaseDirectBuffers( p_vout );
if( p_sys->p_blend->p_module ) if( p_sys->p_blend->p_module )
module_unneed( p_sys->p_blend, p_sys->p_blend->p_module ); module_unneed( p_sys->p_blend, p_sys->p_blend->p_module );
vlc_object_detach( p_sys->p_blend ); vlc_object_detach( p_sys->p_blend );
...@@ -594,66 +577,58 @@ static void Render( vout_thread_t *p_vout, picture_t *p_inpic ) ...@@ -594,66 +577,58 @@ static void Render( vout_thread_t *p_vout, picture_t *p_inpic )
vout_DisplayPicture( p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_sys->p_vout, p_outpic );
} }
/*****************************************************************************
* SendEvents: forward mouse and keyboard events to the parent p_vout
*****************************************************************************/
static int SendEvents( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_this); VLC_UNUSED(oldval);
var_Set( (vlc_object_t *)p_data, psz_var, newval );
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* MouseEvent: callback for mouse events * MouseEvent: callback for mouse events
*****************************************************************************/ *****************************************************************************/
static int MouseEvent( vlc_object_t *p_this, char const *psz_var, static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data ) vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
VLC_UNUSED(p_this); VLC_UNUSED(oldval); vout_thread_t *p_vout = p_data;
vout_thread_t *p_vout = (vout_thread_t*)p_data; assert( p_this == VLC_OBJECT(p_vout->p_sys->p_vout) );
vout_sys_t *p_sys = p_vout->p_sys; VLC_UNUSED(oldval);
vlc_value_t valb;
int i_delta;
var_Get( p_vout->p_sys->p_vout, "mouse-button-down", &valb );
i_delta = newval.i_int - oldval.i_int; vout_sys_t *p_sys = p_vout->p_sys;
const int i_delta = newval.i_int - oldval.i_int;
const int i_bdown = var_GetInteger( p_sys->p_vout, "mouse-button-down" );
if( (valb.i_int & 0x1) == 0 ) if( (i_bdown & 0x1) == 0 )
{ goto forward;
return VLC_SUCCESS;
}
int i_x, i_y;
int i_dx = 0;
int i_dy = 0;
if( psz_var[6] == 'x' ) if( psz_var[6] == 'x' )
{ {
vlc_value_t valy; i_y = var_GetInteger( p_sys->p_vout, "mouse-y" );
var_Get( p_vout->p_sys->p_vout, "mouse-y", &valy ); i_x = newval.i_int;
if( newval.i_int >= (int)p_sys->posx && i_dx = i_delta;
valy.i_int >= (int)p_sys->posy &&
newval.i_int <= (int)(p_sys->posx + p_sys->i_width) &&
valy.i_int <= (int)(p_sys->posy + p_sys->i_height) )
{
p_sys->posx = __MIN( __MAX( p_sys->posx + i_delta, 0 ),
p_vout->output.i_width - p_sys->i_width );
}
} }
else if( psz_var[6] == 'y' ) else if( psz_var[6] == 'y' )
{ {
vlc_value_t valx; i_y = newval.i_int;
var_Get( p_vout->p_sys->p_vout, "mouse-x", &valx ); i_x = var_GetInteger( p_sys->p_vout, "mouse-x" );
if( valx.i_int >= (int)p_sys->posx && i_dy = i_delta;
newval.i_int >= (int)p_sys->posy && }
valx.i_int <= (int)(p_sys->posx + p_sys->i_width) && else
newval.i_int <= (int)(p_sys->posy + p_sys->i_height) ) {
{ goto forward;
p_sys->posy = __MIN( __MAX( p_sys->posy + i_delta, 0 ),
p_vout->output.i_height - p_sys->i_height );
}
} }
/* FIXME missing lock */
if( i_x < (int)p_sys->posx ||
i_y < (int)p_sys->posy ||
i_x > (int)(p_sys->posx + p_sys->i_width) ||
i_y > (int)(p_sys->posy + p_sys->i_height) )
goto forward;
p_sys->posx = __MIN( __MAX( p_sys->posx + i_dx, 0 ),
p_vout->output.i_width - p_sys->i_width );
p_sys->posy = __MIN( __MAX( p_sys->posy + i_dy, 0 ),
p_vout->output.i_height - p_sys->i_height );
return VLC_SUCCESS; return VLC_SUCCESS;
forward:
return var_Set( p_vout, psz_var, newval );
} }
/***************************************************************************** /*****************************************************************************
...@@ -664,18 +639,6 @@ static int Control( vout_thread_t *p_vout, int i_query, va_list args ) ...@@ -664,18 +639,6 @@ static int Control( vout_thread_t *p_vout, int i_query, va_list args )
return vout_vaControl( p_vout->p_sys->p_vout, i_query, args ); return vout_vaControl( p_vout->p_sys->p_vout, i_query, args );
} }
/*****************************************************************************
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* filter_sys_t: logo filter descriptor * filter_sys_t: logo filter descriptor
*****************************************************************************/ *****************************************************************************/
...@@ -769,11 +732,6 @@ static void DestroyFilter( vlc_object_t *p_this ) ...@@ -769,11 +732,6 @@ static void DestroyFilter( vlc_object_t *p_this )
filter_t *p_filter = (filter_t *)p_this; filter_t *p_filter = (filter_t *)p_this;
filter_sys_t *p_sys = p_filter->p_sys; filter_sys_t *p_sys = p_filter->p_sys;
vlc_mutex_destroy( &p_sys->p_logo_list->lock );
FreeLogoList( p_sys->p_logo_list );
free( p_sys->p_logo_list );
free( p_sys );
/* Delete the logo variables from INPUT */ /* Delete the logo variables from INPUT */
var_Destroy( p_filter->p_libvlc, "logo-file" ); var_Destroy( p_filter->p_libvlc, "logo-file" );
var_Destroy( p_filter->p_libvlc, "logo-x" ); var_Destroy( p_filter->p_libvlc, "logo-x" );
...@@ -782,6 +740,11 @@ static void DestroyFilter( vlc_object_t *p_this ) ...@@ -782,6 +740,11 @@ static void DestroyFilter( vlc_object_t *p_this )
var_Destroy( p_filter->p_libvlc, "logo-repeat" ); var_Destroy( p_filter->p_libvlc, "logo-repeat" );
var_Destroy( p_filter->p_libvlc, "logo-position" ); var_Destroy( p_filter->p_libvlc, "logo-position" );
var_Destroy( p_filter->p_libvlc, "logo-transparency" ); var_Destroy( p_filter->p_libvlc, "logo-transparency" );
vlc_mutex_destroy( &p_sys->p_logo_list->lock );
FreeLogoList( p_sys->p_logo_list );
free( p_sys->p_logo_list );
free( p_sys );
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <vlc_vout.h> #include <vlc_vout.h>
#include <math.h> #include <math.h>
#include <assert.h>
#include "filter_common.h" #include "filter_common.h"
#include "filter_picture.h" #include "filter_picture.h"
...@@ -64,10 +65,8 @@ static int Init ( vout_thread_t * ); ...@@ -64,10 +65,8 @@ static int Init ( vout_thread_t * );
static void End ( vout_thread_t * ); static void End ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * ); static void Render ( vout_thread_t *, picture_t * );
static int SendEvents ( vlc_object_t *, char const *, static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
static int MouseEvent ( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static void DrawZoomStatus( uint8_t *, int i_pitch, int i_width, int i_height, static void DrawZoomStatus( uint8_t *, int i_pitch, int i_width, int i_height,
int i_offset_x, int i_offset_y, bool b_visible ); int i_offset_x, int i_offset_y, bool b_visible );
...@@ -144,13 +143,12 @@ static int Create( vlc_object_t *p_this ) ...@@ -144,13 +143,12 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index;
picture_t *p_pic;
video_format_t fmt; video_format_t fmt;
memset( &fmt, 0, sizeof(video_format_t) );
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
memset( &fmt, 0, sizeof(video_format_t) );
/* Initialize the output structure */ /* Initialize the output structure */
p_vout->output.i_chroma = p_vout->render.i_chroma; p_vout->output.i_chroma = p_vout->render.i_chroma;
p_vout->output.i_width = p_vout->render.i_width; p_vout->output.i_width = p_vout->render.i_width;
...@@ -180,14 +178,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -180,14 +178,9 @@ static int Init( vout_thread_t *p_vout )
p_vout->p_sys->i_last_activity = mdate(); p_vout->p_sys->i_last_activity = mdate();
p_vout->p_sys->i_hide_timeout = 1000 * var_GetInteger( p_vout, "mouse-hide-timeout" ); p_vout->p_sys->i_hide_timeout = 1000 * var_GetInteger( p_vout, "mouse-hide-timeout" );
var_AddCallback( p_vout->p_sys->p_vout, "mouse-x", MouseEvent, p_vout ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
var_AddCallback( p_vout->p_sys->p_vout, "mouse-y", MouseEvent, p_vout );
var_AddCallback( p_vout->p_sys->p_vout, "mouse-clicked",
MouseEvent, p_vout);
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -197,26 +190,14 @@ static int Init( vout_thread_t *p_vout ) ...@@ -197,26 +190,14 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index; vout_sys_t *p_sys = p_vout->p_sys;
DEL_PARENT_CALLBACKS( SendEventsToChild );
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
vout_CloseAndRelease( p_sys->p_vout );
/* Free the fake output buffers we allocated */ vout_filter_ReleaseDirectBuffers( p_vout );
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
var_DelCallback( p_vout->p_sys->p_vout, "mouse-x", MouseEvent, p_vout);
var_DelCallback( p_vout->p_sys->p_vout, "mouse-y", MouseEvent, p_vout);
var_DelCallback( p_vout->p_sys->p_vout, "mouse-clicked", MouseEvent, p_vout);
vlc_mutex_destroy( &p_vout->p_sys->lock ); vlc_mutex_destroy( &p_vout->p_sys->lock );
vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -432,40 +413,16 @@ static void DrawRectangle( uint8_t *pb_dst, int i_pitch, int i_width, int i_heig ...@@ -432,40 +413,16 @@ static void DrawRectangle( uint8_t *pb_dst, int i_pitch, int i_width, int i_heig
vlc_memset( &pb_dst[(y+i_h-1) * i_pitch + x], 0xff, i_w ); vlc_memset( &pb_dst[(y+i_h-1) * i_pitch + x], 0xff, i_w );
} }
/*****************************************************************************
* SendEvents: forward mouse and keyboard events to the parent p_vout
*****************************************************************************/
static int SendEvents( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_this); VLC_UNUSED(oldval);
var_Set( (vlc_object_t *)p_data, psz_var, newval );
return VLC_SUCCESS;
}
/*****************************************************************************
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* MouseEvent: callback for mouse events * MouseEvent: callback for mouse events
*****************************************************************************/ *****************************************************************************/
static int MouseEvent( vlc_object_t *p_this, char const *psz_var, static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data ) vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
vout_thread_t *p_vout = (vout_thread_t*)p_data; vout_thread_t *p_vout = p_data;
vlc_value_t vald,valx,valy; vlc_value_t vald,valx,valy;
VLC_UNUSED(p_this); assert( p_this == VLC_OBJECT(p_vout->p_sys->p_vout) );
#define MOUSE_DOWN 1 #define MOUSE_DOWN 1
#define MOUSE_CLICKED 2 #define MOUSE_CLICKED 2
...@@ -567,5 +524,7 @@ static int MouseEvent( vlc_object_t *p_this, char const *psz_var, ...@@ -567,5 +524,7 @@ static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
p_vout->p_sys->i_last_activity = mdate(); p_vout->p_sys->i_last_activity = mdate();
vlc_mutex_unlock( &p_vout->p_sys->lock ); vlc_mutex_unlock( &p_vout->p_sys->lock );
/* FIXME forward event when not grabbed */
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -57,8 +57,6 @@ static int Init ( vout_thread_t * ); ...@@ -57,8 +57,6 @@ static int Init ( vout_thread_t * );
static void End ( vout_thread_t * ); static void End ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * ); static void Render ( vout_thread_t *, picture_t * );
static int SendEvents( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static void ReleaseImages( vout_thread_t *p_vout ); static void ReleaseImages( vout_thread_t *p_vout );
static void VlcPictureToIplImage( vout_thread_t *p_vout, picture_t *p_in ); static void VlcPictureToIplImage( vout_thread_t *p_vout, picture_t *p_in );
...@@ -297,8 +295,6 @@ static int Create( vlc_object_t *p_this ) ...@@ -297,8 +295,6 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index;
picture_t *p_pic;
video_format_t fmt; video_format_t fmt;
vout_sys_t *p_sys = p_vout->p_sys; vout_sys_t *p_sys = p_vout->p_sys;
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
...@@ -358,11 +354,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -358,11 +354,9 @@ static int Init( vout_thread_t *p_vout )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, NULL, NULL, true );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -372,30 +366,22 @@ static int Init( vout_thread_t *p_vout ) ...@@ -372,30 +366,22 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index; vout_sys_t *p_sys = p_vout->p_sys;
DEL_PARENT_CALLBACKS( SendEventsToChild );
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_DelChild( p_vout, p_sys->p_vout, NULL, NULL, true );
vout_CloseAndRelease( p_sys->p_vout );
/* Free the fake output buffers we allocated */ vout_filter_ReleaseDirectBuffers( p_vout );
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
if ( p_vout->p_sys->p_opencv ) if( p_sys->p_opencv )
{ {
//release the internal opencv filter //release the internal opencv filter
if( p_vout->p_sys->p_opencv->p_module ) if( p_sys->p_opencv->p_module )
module_unneed( p_vout->p_sys->p_opencv, p_vout->p_sys->p_opencv->p_module ); module_unneed( p_sys->p_opencv, p_sys->p_opencv->p_module );
vlc_object_detach( p_vout->p_sys->p_opencv ); vlc_object_detach( p_sys->p_opencv );
vlc_object_release( p_vout->p_sys->p_opencv ); vlc_object_release( p_sys->p_opencv );
p_vout->p_sys->p_opencv = NULL; p_sys->p_opencv = NULL;
} }
vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -595,24 +581,3 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -595,24 +581,3 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );
} }
/*****************************************************************************
* SendEvents: forward mouse and keyboard events to the parent p_vout
*****************************************************************************/
static int SendEvents( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
var_Set( (vlc_object_t *)p_data, psz_var, newval );
return VLC_SUCCESS;
}
/*****************************************************************************
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
}
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_vout.h> #include <vlc_vout.h>
#include <assert.h>
#include "filter_common.h" #include "filter_common.h"
...@@ -72,8 +73,12 @@ static void RenderPackedRGB ( vout_thread_t *, picture_t * ); ...@@ -72,8 +73,12 @@ static void RenderPackedRGB ( vout_thread_t *, picture_t * );
static void RemoveAllVout ( vout_thread_t *p_vout ); static void RemoveAllVout ( vout_thread_t *p_vout );
static int SendEvents( vlc_object_t *, char const *, static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
static int FullscreenEventUp( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int FullscreenEventDown( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -646,7 +651,6 @@ static int AdjustHeight( vout_thread_t *p_vout ) ...@@ -646,7 +651,6 @@ static int AdjustHeight( vout_thread_t *p_vout )
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index, i_row, i_col; int i_index, i_row, i_col;
picture_t *p_pic;
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
...@@ -839,7 +843,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -839,7 +843,9 @@ static int Init( vout_thread_t *p_vout )
RemoveAllVout( p_vout ); RemoveAllVout( p_vout );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
ADD_CALLBACKS( p_entry->p_vout, SendEvents ); vout_filter_SetupChild( p_vout, p_entry->p_vout,
MouseEvent, FullscreenEventUp, FullscreenEventDown, true );
#ifdef OVERLAP #ifdef OVERLAP
p_entry->p_vout->i_alignment = 0; p_entry->p_vout->i_alignment = 0;
if (i_col == 0) if (i_col == 0)
...@@ -867,9 +873,7 @@ static int Init( vout_thread_t *p_vout ) ...@@ -867,9 +873,7 @@ static int Init( vout_thread_t *p_vout )
} }
} }
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -879,19 +883,10 @@ static int Init( vout_thread_t *p_vout ) ...@@ -879,19 +883,10 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index;
DEL_PARENT_CALLBACKS( SendEventsToChild );
/* Free the fake output buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
RemoveAllVout( p_vout ); RemoveAllVout( p_vout );
vout_filter_ReleaseDirectBuffers( p_vout );
#ifdef OVERLAP #ifdef OVERLAP
var_SetInteger( p_vout, "bz-length", p_vout->p_sys->bz_length); var_SetInteger( p_vout, "bz-length", p_vout->p_sys->bz_length);
#endif #endif
...@@ -1841,13 +1836,16 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1841,13 +1836,16 @@ static void RenderPackedYUV( vout_thread_t *p_vout, picture_t *p_pic )
*****************************************************************************/ *****************************************************************************/
static void RemoveAllVout( vout_thread_t *p_vout ) static void RemoveAllVout( vout_thread_t *p_vout )
{ {
vout_sys_t *p_sys = p_vout->p_sys;
for( int i = 0; i < p_vout->p_sys->i_vout; i++ ) for( int i = 0; i < p_vout->p_sys->i_vout; i++ )
{ {
if( p_vout->p_sys->pp_vout[i].b_active ) if( p_sys->pp_vout[i].b_active )
{ {
DEL_CALLBACKS( p_vout->p_sys->pp_vout[i].p_vout, SendEvents ); vout_filter_SetupChild( p_vout, p_sys->pp_vout[i].p_vout,
vout_CloseAndRelease( p_vout->p_sys->pp_vout[i].p_vout ); MouseEvent, FullscreenEventUp, FullscreenEventDown, true );
p_vout->p_sys->pp_vout[i].p_vout = NULL; vout_CloseAndRelease( p_sys->pp_vout[i].p_vout );
p_sys->pp_vout[i].p_vout = NULL;
} }
} }
} }
...@@ -1855,78 +1853,102 @@ static void RemoveAllVout( vout_thread_t *p_vout ) ...@@ -1855,78 +1853,102 @@ static void RemoveAllVout( vout_thread_t *p_vout )
/***************************************************************************** /*****************************************************************************
* SendEvents: forward mouse and keyboard events to the parent p_vout * SendEvents: forward mouse and keyboard events to the parent p_vout
*****************************************************************************/ *****************************************************************************/
static int SendEvents( vlc_object_t *p_this, char const *psz_var, static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *_p_vout ) vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
vout_thread_t *p_vout = p_data;
vout_sys_t *p_sys = p_vout->p_sys;
VLC_UNUSED(oldval); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
int i_vout; int i_vout;
vlc_value_t sentval = newval;
/* Find the video output index */ /* Find the video output index */
for( i_vout = 0; i_vout < p_vout->p_sys->i_vout; i_vout++ ) for( i_vout = 0; i_vout < p_sys->i_vout; i_vout++ )
{ {
if( p_this == (vlc_object_t *)p_vout->p_sys->pp_vout[ i_vout ].p_vout ) if( p_sys->pp_vout[i_vout].b_active &&
{ p_this == VLC_OBJECT(p_sys->pp_vout[i_vout].p_vout) )
break; break;
}
}
if( i_vout == p_vout->p_sys->i_vout )
{
return VLC_EGENERIC;
} }
assert( i_vout < p_vout->p_sys->i_vout );
/* Translate the mouse coordinates */ /* Translate the mouse coordinates */
if( !strcmp( psz_var, "mouse-x" ) ) if( !strcmp( psz_var, "mouse-x" ) )
{ {
#ifdef OVERLAP #ifdef OVERLAP
int i_overlap = ((p_vout->p_sys->i_col > 2) ? 0 : 2 * p_vout->p_sys->i_halfLength); int i_overlap = ((p_sys->i_col > 2) ? 0 : 2 * p_sys->i_halfLength);
sentval.i_int += (p_vout->output.i_width - i_overlap) newval.i_int += (p_vout->output.i_width - i_overlap)
#else #else
sentval.i_int += p_vout->output.i_width newval.i_int += p_vout->output.i_width
#endif #endif
* (i_vout % p_vout->p_sys->i_col) * (i_vout % p_sys->i_col)
/ p_vout->p_sys->i_col; / p_sys->i_col;
} }
else if( !strcmp( psz_var, "mouse-y" ) ) else if( !strcmp( psz_var, "mouse-y" ) )
{ {
#ifdef OVERLAP #ifdef OVERLAP
int i_overlap = ((p_vout->p_sys->i_row > 2) ? 0 : 2 * p_vout->p_sys->i_halfHeight); int i_overlap = ((p_sys->i_row > 2) ? 0 : 2 * p_sys->i_halfHeight);
sentval.i_int += (p_vout->output.i_height - i_overlap) newval.i_int += (p_vout->output.i_height - i_overlap)
#else #else
sentval.i_int += p_vout->output.i_height newval.i_int += p_vout->output.i_height
#endif #endif
//bug fix in Wall plug-in //bug fix in Wall plug-in
// * (i_vout / p_vout->p_sys->i_row) // * (i_vout / p_vout->p_sys->i_row)
* (i_vout / p_vout->p_sys->i_col) * (i_vout / p_sys->i_col)
/ p_vout->p_sys->i_row; / p_sys->i_row;
} }
var_Set( p_vout, psz_var, sentval ); return var_Set( p_vout, psz_var, newval );
}
return VLC_SUCCESS; /**
* Forward fullscreen event to/from the childrens.
* FIXME pretty much duplicated from wall.c
*/
static bool IsFullscreenActive( vout_thread_t *p_vout )
{
vout_sys_t *p_sys = p_vout->p_sys;
for( int i = 0; i < p_sys->i_vout; i++ )
{
if( p_sys->pp_vout[i].b_active &&
var_GetBool( p_sys->pp_vout[i].p_vout, "fullscreen" ) )
return true;
}
return false;
} }
static int FullscreenEventUp( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
vout_thread_t *p_vout = p_data;
VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(newval);
/***************************************************************************** const bool b_fullscreen = IsFullscreenActive( p_vout );
* SendEventsToChild: forward events to the child/children vout if( !var_GetBool( p_vout, "fullscreen" ) != !b_fullscreen )
*****************************************************************************/ return var_SetBool( p_vout, "fullscreen", b_fullscreen );
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var, return VLC_SUCCESS;
vlc_value_t oldval, vlc_value_t newval, void *p_data ) }
static int FullscreenEventDown( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
VLC_UNUSED(oldval); VLC_UNUSED(p_data); vout_thread_t *p_vout = (vout_thread_t*)p_this;
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_sys_t *p_sys = p_vout->p_sys;
int i_row, i_col, i_vout = 0; VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_var);
for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) const bool b_fullscreen = IsFullscreenActive( p_vout );
if( !b_fullscreen != !newval.b_bool )
{ {
for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) for( int i = 0; i < p_sys->i_vout; i++ )
{ {
var_Set( p_vout->p_sys->pp_vout[ i_vout ].p_vout, psz_var, newval); if( !p_sys->pp_vout[i].b_active )
if( !strcmp( psz_var, "fullscreen" ) ) break; continue;
i_vout++;
vout_thread_t *p_child = p_sys->pp_vout[i].p_vout;
if( !var_GetBool( p_child, "fullscreen" ) != !newval.b_bool )
{
var_SetBool( p_child, "fullscreen", newval.b_bool );
if( newval.b_bool )
return VLC_SUCCESS;
}
} }
} }
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -50,8 +50,6 @@ static int Init ( vout_thread_t * ); ...@@ -50,8 +50,6 @@ static int Init ( vout_thread_t * );
static void End ( vout_thread_t * ); static void End ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * ); static void Render ( vout_thread_t *, picture_t * );
static int SendEvents ( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int MouseEvent ( vlc_object_t *, char const *, static int MouseEvent ( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
...@@ -242,8 +240,6 @@ static int Create( vlc_object_t *p_this ) ...@@ -242,8 +240,6 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index;
picture_t *p_pic;
video_format_t fmt; video_format_t fmt;
memset( &fmt, 0, sizeof( video_format_t ) ); memset( &fmt, 0, sizeof( video_format_t ) );
...@@ -270,14 +266,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -270,14 +266,9 @@ static int Init( vout_thread_t *p_vout )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
var_AddCallback( p_vout->p_sys->p_vout, "mouse-x", MouseEvent, p_vout ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
var_AddCallback( p_vout->p_sys->p_vout, "mouse-y", MouseEvent, p_vout );
var_AddCallback( p_vout->p_sys->p_vout, "mouse-clicked",
MouseEvent, p_vout);
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -287,24 +278,12 @@ static int Init( vout_thread_t *p_vout ) ...@@ -287,24 +278,12 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index; vout_sys_t *p_sys = p_vout->p_sys;
DEL_PARENT_CALLBACKS( SendEventsToChild );
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
vout_CloseAndRelease( p_sys->p_vout );
/* Free the fake output buffers we allocated */ vout_filter_ReleaseDirectBuffers( p_vout );
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
var_DelCallback( p_vout->p_sys->p_vout, "mouse-x", MouseEvent, p_vout);
var_DelCallback( p_vout->p_sys->p_vout, "mouse-y", MouseEvent, p_vout);
var_DelCallback( p_vout->p_sys->p_vout, "mouse-clicked", MouseEvent, p_vout);
vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
#define SHUFFLE_WIDTH 81 #define SHUFFLE_WIDTH 81
...@@ -457,42 +436,18 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -457,42 +436,18 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );
} }
/*****************************************************************************
* SendEvents: forward mouse and keyboard events to the parent p_vout
*****************************************************************************/
static int SendEvents( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_this); VLC_UNUSED(oldval);
var_Set( (vlc_object_t *)p_data, psz_var, newval );
return VLC_SUCCESS;
}
/*****************************************************************************
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
}
/***************************************************************************** /*****************************************************************************
* MouseEvent: callback for mouse events * MouseEvent: callback for mouse events
*****************************************************************************/ *****************************************************************************/
static int MouseEvent( vlc_object_t *p_this, char const *psz_var, static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data ) vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(newval); vout_thread_t *p_vout = p_data;
vout_thread_t *p_vout = (vout_thread_t*)p_data; VLC_UNUSED(p_this); VLC_UNUSED(oldval);
int i_x, i_y; int i_x, i_y;
int i_v; int i_v;
/* FIXME missing lock */
#define MOUSE_DOWN 1 #define MOUSE_DOWN 1
#define MOUSE_CLICKED 2 #define MOUSE_CLICKED 2
#define MOUSE_MOVE_X 4 #define MOUSE_MOVE_X 4
...@@ -552,6 +507,8 @@ static int MouseEvent( vlc_object_t *p_this, char const *psz_var, ...@@ -552,6 +507,8 @@ static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
p_vout->p_sys->b_finished = finished( p_vout->p_sys ); p_vout->p_sys->b_finished = finished( p_vout->p_sys );
} }
} }
/* FIXME do we want to forward it or not ? */
var_Set( p_vout, psz_var, newval );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
...@@ -56,7 +56,7 @@ static void FilterPlanar( vout_thread_t *, const picture_t *, picture_t * ); ...@@ -56,7 +56,7 @@ static void FilterPlanar( vout_thread_t *, const picture_t *, picture_t * );
static void FilterI422( vout_thread_t *, const picture_t *, picture_t * ); static void FilterI422( vout_thread_t *, const picture_t *, picture_t * );
static void FilterYUYV( vout_thread_t *, const picture_t *, picture_t * ); static void FilterYUYV( vout_thread_t *, const picture_t *, picture_t * );
static int SendEvents( vlc_object_t *, char const *, static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
/***************************************************************************** /*****************************************************************************
...@@ -216,8 +216,6 @@ static int Create( vlc_object_t *p_this ) ...@@ -216,8 +216,6 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index;
picture_t *p_pic;
video_format_t fmt; video_format_t fmt;
I_OUTPUTPICTURES = 0; I_OUTPUTPICTURES = 0;
...@@ -260,11 +258,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -260,11 +258,9 @@ static int Init( vout_thread_t *p_vout )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
ADD_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
ADD_PARENT_CALLBACKS( SendEventsToChild ); vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -274,20 +270,12 @@ static int Init( vout_thread_t *p_vout ) ...@@ -274,20 +270,12 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index; vout_sys_t *p_sys = p_vout->p_sys;
DEL_PARENT_CALLBACKS( SendEventsToChild ); vout_filter_DelChild( p_vout, p_sys->p_vout, MouseEvent );
vout_CloseAndRelease( p_sys->p_vout );
DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents ); vout_filter_ReleaseDirectBuffers( p_vout );
/* Free the fake output buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
vout_CloseAndRelease( p_vout->p_sys->p_vout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -334,32 +322,32 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -334,32 +322,32 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic ); vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );
} }
/***************************************************************************** /**
* SendEvents: forward mouse and keyboard events to the parent p_vout * Forward mouse event with proper conversion.
*****************************************************************************/ */
static int SendEvents( vlc_object_t *p_this, char const *psz_var, static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *_p_vout ) vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
vout_thread_t *p_vout = p_data;
VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
vlc_value_t sentval = newval;
/* Translate the mouse coordinates */ /* Translate the mouse coordinates
* FIXME missing lock */
if( !strcmp( psz_var, "mouse-x" ) ) if( !strcmp( psz_var, "mouse-x" ) )
{ {
switch( p_vout->p_sys->i_mode ) switch( p_vout->p_sys->i_mode )
{ {
case TRANSFORM_MODE_270: case TRANSFORM_MODE_270:
sentval.i_int = p_vout->p_sys->p_vout->output.i_width newval.i_int = p_vout->p_sys->p_vout->output.i_width
- sentval.i_int; - newval.i_int;
case TRANSFORM_MODE_90: case TRANSFORM_MODE_90:
var_Set( p_vout, "mouse-y", sentval ); psz_var = "mouse-y";
return VLC_SUCCESS; break;
case TRANSFORM_MODE_180: case TRANSFORM_MODE_180:
case TRANSFORM_MODE_HFLIP: case TRANSFORM_MODE_HFLIP:
sentval.i_int = p_vout->p_sys->p_vout->output.i_width newval.i_int = p_vout->p_sys->p_vout->output.i_width
- sentval.i_int; - newval.i_int;
break; break;
case TRANSFORM_MODE_VFLIP: case TRANSFORM_MODE_VFLIP:
...@@ -372,16 +360,16 @@ static int SendEvents( vlc_object_t *p_this, char const *psz_var, ...@@ -372,16 +360,16 @@ static int SendEvents( vlc_object_t *p_this, char const *psz_var,
switch( p_vout->p_sys->i_mode ) switch( p_vout->p_sys->i_mode )
{ {
case TRANSFORM_MODE_90: case TRANSFORM_MODE_90:
sentval.i_int = p_vout->p_sys->p_vout->output.i_height newval.i_int = p_vout->p_sys->p_vout->output.i_height
- sentval.i_int; - newval.i_int;
case TRANSFORM_MODE_270: case TRANSFORM_MODE_270:
var_Set( p_vout, "mouse-x", sentval ); psz_var = "mouse-x";
return VLC_SUCCESS; break;
case TRANSFORM_MODE_180: case TRANSFORM_MODE_180:
case TRANSFORM_MODE_VFLIP: case TRANSFORM_MODE_VFLIP:
sentval.i_int = p_vout->p_sys->p_vout->output.i_height newval.i_int = p_vout->p_sys->p_vout->output.i_height
- sentval.i_int; - newval.i_int;
break; break;
case TRANSFORM_MODE_HFLIP: case TRANSFORM_MODE_HFLIP:
...@@ -390,21 +378,7 @@ static int SendEvents( vlc_object_t *p_this, char const *psz_var, ...@@ -390,21 +378,7 @@ static int SendEvents( vlc_object_t *p_this, char const *psz_var,
} }
} }
var_Set( p_vout, psz_var, sentval ); return var_Set( p_vout, psz_var, newval );
return VLC_SUCCESS;
}
/*****************************************************************************
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
VLC_UNUSED(p_data); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)p_this;
var_Set( p_vout->p_sys->p_vout, psz_var, newval );
return VLC_SUCCESS;
} }
static void FilterPlanar( vout_thread_t *p_vout, static void FilterPlanar( vout_thread_t *p_vout,
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_vout.h> #include <vlc_vout.h>
#include <assert.h>
#include "filter_common.h" #include "filter_common.h"
...@@ -47,8 +48,12 @@ static void Render ( vout_thread_t *, picture_t * ); ...@@ -47,8 +48,12 @@ static void Render ( vout_thread_t *, picture_t * );
static void RemoveAllVout ( vout_thread_t *p_vout ); static void RemoveAllVout ( vout_thread_t *p_vout );
static int SendEvents( vlc_object_t *, char const *, static int MouseEvent( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void * );
static int FullscreenEventUp( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static int FullscreenEventDown( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -237,9 +242,8 @@ static int Create( vlc_object_t *p_this ) ...@@ -237,9 +242,8 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Init( vout_thread_t *p_vout ) static int Init( vout_thread_t *p_vout )
{ {
int i_index, i_row, i_col, i_width, i_height, i_left, i_top; int i_row, i_col, i_width, i_height, i_left, i_top;
unsigned int i_target_width,i_target_height; unsigned int i_target_width,i_target_height;
picture_t *p_pic;
video_format_t fmt; video_format_t fmt;
int i_aspect = 4*VOUT_ASPECT_FACTOR/3; int i_aspect = 4*VOUT_ASPECT_FACTOR/3;
int i_align = 0; int i_align = 0;
...@@ -430,16 +434,13 @@ static int Init( vout_thread_t *p_vout ) ...@@ -430,16 +434,13 @@ static int Init( vout_thread_t *p_vout )
RemoveAllVout( p_vout ); RemoveAllVout( p_vout );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
ADD_CALLBACKS( vout_filter_SetupChild( p_vout, p_vout->p_sys->pp_vout[p_vout->p_sys->i_vout].p_vout,
p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout, MouseEvent, FullscreenEventUp, FullscreenEventDown, true );
SendEvents );
p_vout->p_sys->i_vout++; p_vout->p_sys->i_vout++;
} }
} }
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES ); vout_filter_AllocateDirectBuffers( p_vout, VOUT_MAX_PICTURES );
ADD_PARENT_CALLBACKS( SendEventsToChild );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -449,18 +450,9 @@ static int Init( vout_thread_t *p_vout ) ...@@ -449,18 +450,9 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
int i_index;
DEL_PARENT_CALLBACKS( SendEventsToChild );
/* Free the fake output buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
RemoveAllVout( p_vout ); RemoveAllVout( p_vout );
vout_filter_ReleaseDirectBuffers( p_vout );
} }
/***************************************************************************** /*****************************************************************************
...@@ -575,82 +567,98 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -575,82 +567,98 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
*****************************************************************************/ *****************************************************************************/
static void RemoveAllVout( vout_thread_t *p_vout ) static void RemoveAllVout( vout_thread_t *p_vout )
{ {
while( p_vout->p_sys->i_vout ) vout_sys_t *p_sys = p_vout->p_sys;
while( p_sys->i_vout )
{ {
--p_vout->p_sys->i_vout; p_sys->i_vout--;
if( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].b_active ) if( p_sys->pp_vout[p_sys->i_vout ].b_active )
{ {
DEL_CALLBACKS( vout_filter_SetupChild( p_vout, p_sys->pp_vout[p_sys->i_vout].p_vout,
p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout, MouseEvent, FullscreenEventUp, FullscreenEventDown, false );
SendEvents ); vout_CloseAndRelease( p_sys->pp_vout[p_sys->i_vout].p_vout );
vout_CloseAndRelease( p_vout->p_sys->pp_vout[ p_vout->p_sys->i_vout ].p_vout ); }
}
} }
} }
/***************************************************************************** /**
* SendEvents: forward mouse and keyboard events to the parent p_vout * Forward mouse event with proper conversion.
*****************************************************************************/ */
static int SendEvents( vlc_object_t *p_this, char const *psz_var, static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *_p_vout ) vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
vout_thread_t *p_vout = p_data;
vout_sys_t *p_sys = p_vout->p_sys;
VLC_UNUSED(oldval); VLC_UNUSED(oldval);
vout_thread_t *p_vout = (vout_thread_t *)_p_vout;
int i_vout; int i_vout;
vlc_value_t sentval = newval;
/* Find the video output index */ /* Find the video output index */
for( i_vout = 0; i_vout < p_vout->p_sys->i_vout; i_vout++ ) for( i_vout = 0; i_vout < p_sys->i_vout; i_vout++ )
{ {
if( p_this == (vlc_object_t *)p_vout->p_sys->pp_vout[ i_vout ].p_vout ) if( p_sys->pp_vout[i_vout].b_active &&
{ p_this == VLC_OBJECT(p_sys->pp_vout[i_vout].p_vout) )
break; break;
}
}
if( i_vout == p_vout->p_sys->i_vout )
{
return VLC_EGENERIC;
} }
assert( i_vout < p_vout->p_sys->i_vout );
/* Translate the mouse coordinates */ /* Translate the mouse coordinates */
if( !strcmp( psz_var, "mouse-x" ) ) if( !strcmp( psz_var, "mouse-x" ) )
{ newval.i_int += p_vout->output.i_width * (i_vout % p_sys->i_col) / p_sys->i_col;
sentval.i_int += p_vout->output.i_width
* (i_vout % p_vout->p_sys->i_col)
/ p_vout->p_sys->i_col;
}
else if( !strcmp( psz_var, "mouse-y" ) ) else if( !strcmp( psz_var, "mouse-y" ) )
newval.i_int += p_vout->output.i_height * (i_vout / p_sys->i_row) / p_sys->i_row;
return var_Set( p_vout, psz_var, newval );
}
/**
* Forward fullscreen event to/from the childrens.
*/
static bool IsFullscreenActive( vout_thread_t *p_vout )
{
vout_sys_t *p_sys = p_vout->p_sys;
for( int i = 0; i < p_sys->i_vout; i++ )
{ {
sentval.i_int += p_vout->output.i_height if( p_sys->pp_vout[i].b_active &&
* (i_vout / p_vout->p_sys->i_row) var_GetBool( p_sys->pp_vout[i].p_vout, "fullscreen" ) )
/ p_vout->p_sys->i_row; return true;
} }
return false;
}
static int FullscreenEventUp( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
vout_thread_t *p_vout = p_data;
VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(newval);
var_Set( p_vout, psz_var, sentval ); const bool b_fullscreen = IsFullscreenActive( p_vout );
if( !var_GetBool( p_vout, "fullscreen" ) != !b_fullscreen )
return var_SetBool( p_vout, "fullscreen", b_fullscreen );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
static int FullscreenEventDown( vlc_object_t *p_this, char const *psz_var,
/***************************************************************************** vlc_value_t oldval, vlc_value_t newval, void *p_data )
* SendEventsToChild: forward events to the child/children vout
*****************************************************************************/
static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
VLC_UNUSED(p_data); VLC_UNUSED(oldval); vout_thread_t *p_vout = (vout_thread_t*)p_this;
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_sys_t *p_sys = p_vout->p_sys;
int i_row, i_col, i_vout = 0; VLC_UNUSED(oldval); VLC_UNUSED(p_data); VLC_UNUSED(psz_var);
for( i_row = 0; i_row < p_vout->p_sys->i_row; i_row++ ) const bool b_fullscreen = IsFullscreenActive( p_vout );
if( !b_fullscreen != !newval.b_bool )
{ {
for( i_col = 0; i_col < p_vout->p_sys->i_col; i_col++ ) for( int i = 0; i < p_sys->i_vout; i++ )
{ {
var_Set( p_vout->p_sys->pp_vout[ i_vout ].p_vout, psz_var, newval); if( !p_sys->pp_vout[i].b_active )
if( !strcmp( psz_var, "fullscreen" ) ) break; continue;
i_vout++;
vout_thread_t *p_child = p_sys->pp_vout[i].p_vout;
if( !var_GetBool( p_child, "fullscreen" ) != !newval.b_bool )
{
var_SetBool( p_child, "fullscreen", newval.b_bool );
if( newval.b_bool )
return VLC_SUCCESS;
}
} }
} }
return VLC_SUCCESS; return VLC_SUCCESS;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment